Imported Upstream version 8.6.6 upstream/8.6.6
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 18 Dec 2020 03:15:52 +0000 (12:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 18 Dec 2020 03:15:52 +0000 (12:15 +0900)
492 files changed:
README
changes
doc/Access.3
doc/AddErrInfo.3
doc/Alloc.3
doc/AllowExc.3
doc/AppInit.3
doc/AssocData.3
doc/Async.3
doc/BackgdErr.3
doc/Backslash.3
doc/BoolObj.3
doc/ByteArrObj.3
doc/Cancel.3
doc/CrtChannel.3
doc/CrtCommand.3
doc/CrtMathFnc.3
doc/CrtObjCmd.3
doc/CrtSlave.3
doc/CrtTrace.3
doc/DoOneEvent.3
doc/DoubleObj.3
doc/DumpActiveMemory.3
doc/Ensemble.3
doc/Eval.3
doc/Exit.3
doc/ExprLong.3
doc/FileSystem.3
doc/GetHostName.3
doc/GetStdChan.3
doc/GetVersion.3
doc/Hash.3
doc/IntObj.3
doc/Interp.3
doc/ListObj.3
doc/NRE.3
doc/Notifier.3
doc/ObjectType.3
doc/Panic.3
doc/PkgRequire.3
doc/RegExp.3
doc/SaveResult.3
doc/SetResult.3
doc/SetVar.3
doc/Tcl.n
doc/Tcl_Main.3
doc/TraceCmd.3
doc/TraceVar.3
doc/Translate.3
doc/UniCharIsAlpha.3
doc/UpVar.3
doc/WrongNumArgs.3
doc/after.n
doc/append.n
doc/apply.n
doc/array.n
doc/bgerror.n
doc/binary.n
doc/catch.n
doc/chan.n
doc/dde.n
doc/encoding.n
doc/error.n
doc/exec.n
doc/expr.n
doc/fconfigure.n
doc/fcopy.n
doc/file.n
doc/fileevent.n
doc/filename.n
doc/format.n
doc/global.n
doc/http.n
doc/lindex.n
doc/linsert.n
doc/llength.n
doc/lmap.n
doc/lrange.n
doc/lsearch.n
doc/lset.n
doc/lsort.n
doc/mathfunc.n
doc/memory.n
doc/msgcat.n
doc/open.n
doc/package.n
doc/pkgMkIndex.n
doc/proc.n
doc/read.n
doc/regexp.n
doc/regsub.n
doc/return.n
doc/safe.n
doc/scan.n
doc/set.n
doc/socket.n
doc/string.n
doc/subst.n
doc/tcltest.n
doc/tclvars.n
doc/trace.n
doc/transchan.n
doc/try.n
doc/unknown.n
doc/unload.n
doc/unset.n
doc/update.n
doc/uplevel.n
doc/upvar.n
doc/variable.n
doc/vwait.n
doc/while.n
doc/zlib.n
generic/regc_lex.c
generic/regc_locale.c
generic/tcl.h
generic/tclAssembly.c
generic/tclBasic.c
generic/tclClock.c
generic/tclCmdAH.c
generic/tclCmdIL.c
generic/tclCmdMZ.c
generic/tclCompCmdsGR.c
generic/tclCompCmdsSZ.c
generic/tclCompExpr.c
generic/tclCompile.c
generic/tclCompile.h
generic/tclDate.c
generic/tclDictObj.c
generic/tclDisassemble.c
generic/tclEnsemble.c
generic/tclEvent.c
generic/tclExecute.c
generic/tclFileName.c
generic/tclIO.c
generic/tclIO.h
generic/tclIORChan.c
generic/tclIOUtil.c
generic/tclIndexObj.c
generic/tclInt.h
generic/tclInterp.c
generic/tclNamesp.c
generic/tclOO.c
generic/tclOO.h
generic/tclOOCall.c
generic/tclOODefineCmds.c
generic/tclOOMethod.c
generic/tclObj.c
generic/tclPathObj.c
generic/tclProc.c
generic/tclStringObj.c
generic/tclStringRep.h [new file with mode: 0644]
generic/tclTest.c
generic/tclTestObj.c
generic/tclThreadTest.c
generic/tclUniData.c
generic/tclUtil.c
generic/tclVar.c
generic/tclZlib.c
library/init.tcl
library/reg/pkgIndex.tcl
library/tcltest/pkgIndex.tcl
library/tcltest/tcltest.tcl
library/tzdata/America/Cambridge_Bay
library/tzdata/America/Caracas
library/tzdata/America/Inuvik
library/tzdata/America/Iqaluit
library/tzdata/America/Pangnirtung
library/tzdata/America/Port-au-Prince
library/tzdata/America/Rankin_Inlet
library/tzdata/America/Resolute
library/tzdata/America/Santiago
library/tzdata/America/Yellowknife
library/tzdata/Antarctica/Casey
library/tzdata/Antarctica/Davis
library/tzdata/Antarctica/DumontDUrville
library/tzdata/Antarctica/Macquarie
library/tzdata/Antarctica/Mawson
library/tzdata/Antarctica/Palmer
library/tzdata/Antarctica/Rothera
library/tzdata/Antarctica/Syowa
library/tzdata/Antarctica/Troll
library/tzdata/Antarctica/Vostok
library/tzdata/Asia/Almaty
library/tzdata/Asia/Anadyr
library/tzdata/Asia/Aqtau
library/tzdata/Asia/Aqtobe
library/tzdata/Asia/Baku
library/tzdata/Asia/Barnaul [new file with mode: 0644]
library/tzdata/Asia/Chita
library/tzdata/Asia/Gaza
library/tzdata/Asia/Hebron
library/tzdata/Asia/Irkutsk
library/tzdata/Asia/Kamchatka
library/tzdata/Asia/Khandyga
library/tzdata/Asia/Krasnoyarsk
library/tzdata/Asia/Magadan
library/tzdata/Asia/Novokuznetsk
library/tzdata/Asia/Novosibirsk
library/tzdata/Asia/Omsk
library/tzdata/Asia/Oral
library/tzdata/Asia/Qyzylorda
library/tzdata/Asia/Sakhalin
library/tzdata/Asia/Srednekolymsk
library/tzdata/Asia/Tomsk [new file with mode: 0644]
library/tzdata/Asia/Ust-Nera
library/tzdata/Asia/Vladivostok
library/tzdata/Asia/Yakutsk
library/tzdata/Asia/Yekaterinburg
library/tzdata/Asia/Yerevan
library/tzdata/Europe/Astrakhan [new file with mode: 0644]
library/tzdata/Europe/Chisinau
library/tzdata/Europe/Kaliningrad
library/tzdata/Europe/Kirov [new file with mode: 0644]
library/tzdata/Europe/Minsk
library/tzdata/Europe/Moscow
library/tzdata/Europe/Samara
library/tzdata/Europe/Ulyanovsk [new file with mode: 0644]
library/tzdata/Europe/Vilnius
library/tzdata/Europe/Volgograd
library/tzdata/Indian/Kerguelen
library/tzdata/Pacific/Easter
library/word.tcl
macosx/configure
pkgs/itcl4.0.5/ChangeLog [moved from pkgs/itcl4.0.4/ChangeLog with 100% similarity]
pkgs/itcl4.0.5/Makefile.in [moved from pkgs/itcl4.0.4/Makefile.in with 99% similarity]
pkgs/itcl4.0.5/README [moved from pkgs/itcl4.0.4/README with 100% similarity]
pkgs/itcl4.0.5/TODO [moved from pkgs/itcl4.0.4/TODO with 100% similarity]
pkgs/itcl4.0.5/aclocal.m4 [moved from pkgs/itcl4.0.4/aclocal.m4 with 100% similarity]
pkgs/itcl4.0.5/configure [moved from pkgs/itcl4.0.4/configure with 99% similarity]
pkgs/itcl4.0.5/configure.ac [moved from pkgs/itcl4.0.4/configure.in with 92% similarity]
pkgs/itcl4.0.5/doc/Class.3 [moved from pkgs/itcl4.0.4/doc/Class.3 with 100% similarity]
pkgs/itcl4.0.5/doc/List.3 [moved from pkgs/itcl4.0.4/doc/List.3 with 100% similarity]
pkgs/itcl4.0.5/doc/Object.3 [moved from pkgs/itcl4.0.4/doc/Object.3 with 100% similarity]
pkgs/itcl4.0.5/doc/Preserve.3 [moved from pkgs/itcl4.0.4/doc/Preserve.3 with 100% similarity]
pkgs/itcl4.0.5/doc/RegisterC.3 [moved from pkgs/itcl4.0.4/doc/RegisterC.3 with 100% similarity]
pkgs/itcl4.0.5/doc/Stack.3 [moved from pkgs/itcl4.0.4/doc/Stack.3 with 100% similarity]
pkgs/itcl4.0.5/doc/body.n [moved from pkgs/itcl4.0.4/doc/body.n with 100% similarity]
pkgs/itcl4.0.5/doc/class.n [moved from pkgs/itcl4.0.4/doc/class.n with 100% similarity]
pkgs/itcl4.0.5/doc/code.n [moved from pkgs/itcl4.0.4/doc/code.n with 100% similarity]
pkgs/itcl4.0.5/doc/configbody.n [moved from pkgs/itcl4.0.4/doc/configbody.n with 100% similarity]
pkgs/itcl4.0.5/doc/delete.n [moved from pkgs/itcl4.0.4/doc/delete.n with 100% similarity]
pkgs/itcl4.0.5/doc/ensemble.n [moved from pkgs/itcl4.0.4/doc/ensemble.n with 100% similarity]
pkgs/itcl4.0.5/doc/find.n [moved from pkgs/itcl4.0.4/doc/find.n with 100% similarity]
pkgs/itcl4.0.5/doc/is.n [moved from pkgs/itcl4.0.4/doc/is.n with 100% similarity]
pkgs/itcl4.0.5/doc/itcl.n [moved from pkgs/itcl4.0.4/doc/itcl.n with 100% similarity]
pkgs/itcl4.0.5/doc/itclcomponent.n [moved from pkgs/itcl4.0.4/doc/itclcomponent.n with 100% similarity]
pkgs/itcl4.0.5/doc/itcldelegate.n [moved from pkgs/itcl4.0.4/doc/itcldelegate.n with 100% similarity]
pkgs/itcl4.0.5/doc/itclextendedclass.n [moved from pkgs/itcl4.0.4/doc/itclextendedclass.n with 100% similarity]
pkgs/itcl4.0.5/doc/itcloption.n [moved from pkgs/itcl4.0.4/doc/itcloption.n with 100% similarity]
pkgs/itcl4.0.5/doc/itclvars.n [moved from pkgs/itcl4.0.4/doc/itclvars.n with 100% similarity]
pkgs/itcl4.0.5/doc/itclwidget.n [moved from pkgs/itcl4.0.4/doc/itclwidget.n with 100% similarity]
pkgs/itcl4.0.5/doc/license.terms [moved from pkgs/itcl4.0.4/doc/license.terms with 100% similarity]
pkgs/itcl4.0.5/doc/local.n [moved from pkgs/itcl4.0.4/doc/local.n with 100% similarity]
pkgs/itcl4.0.5/doc/man.macros [moved from pkgs/itcl4.0.4/doc/man.macros with 100% similarity]
pkgs/itcl4.0.5/doc/scope.n [moved from pkgs/itcl4.0.4/doc/scope.n with 100% similarity]
pkgs/itcl4.0.5/generic/clientData [moved from pkgs/itcl4.0.4/generic/clientData with 100% similarity]
pkgs/itcl4.0.5/generic/itcl.decls [moved from pkgs/itcl4.0.4/generic/itcl.decls with 100% similarity]
pkgs/itcl4.0.5/generic/itcl.h [moved from pkgs/itcl4.0.4/generic/itcl.h with 98% similarity]
pkgs/itcl4.0.5/generic/itcl2TclOO.c [moved from pkgs/itcl4.0.4/generic/itcl2TclOO.c with 100% similarity]
pkgs/itcl4.0.5/generic/itcl2TclOO.h [moved from pkgs/itcl4.0.4/generic/itcl2TclOO.h with 100% similarity]
pkgs/itcl4.0.5/generic/itclBase.c [moved from pkgs/itcl4.0.4/generic/itclBase.c with 99% similarity]
pkgs/itcl4.0.5/generic/itclBuiltin.c [moved from pkgs/itcl4.0.4/generic/itclBuiltin.c with 97% similarity]
pkgs/itcl4.0.5/generic/itclClass.c [moved from pkgs/itcl4.0.4/generic/itclClass.c with 98% similarity]
pkgs/itcl4.0.5/generic/itclCmd.c [moved from pkgs/itcl4.0.4/generic/itclCmd.c with 99% similarity]
pkgs/itcl4.0.5/generic/itclDecls.h [moved from pkgs/itcl4.0.4/generic/itclDecls.h with 100% similarity]
pkgs/itcl4.0.5/generic/itclEnsemble.c [moved from pkgs/itcl4.0.4/generic/itclEnsemble.c with 98% similarity]
pkgs/itcl4.0.5/generic/itclHelpers.c [moved from pkgs/itcl4.0.4/generic/itclHelpers.c with 97% similarity]
pkgs/itcl4.0.5/generic/itclInfo.c [moved from pkgs/itcl4.0.4/generic/itclInfo.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclInt.h [moved from pkgs/itcl4.0.4/generic/itclInt.h with 98% similarity]
pkgs/itcl4.0.5/generic/itclIntDecls.h [moved from pkgs/itcl4.0.4/generic/itclIntDecls.h with 100% similarity]
pkgs/itcl4.0.5/generic/itclLinkage.c [moved from pkgs/itcl4.0.4/generic/itclLinkage.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclMethod.c [moved from pkgs/itcl4.0.4/generic/itclMethod.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclMigrate2TclCore.c [moved from pkgs/itcl4.0.4/generic/itclMigrate2TclCore.c with 96% similarity]
pkgs/itcl4.0.5/generic/itclMigrate2TclCore.h [moved from pkgs/itcl4.0.4/generic/itclMigrate2TclCore.h with 96% similarity]
pkgs/itcl4.0.5/generic/itclObject.c [moved from pkgs/itcl4.0.4/generic/itclObject.c with 98% similarity]
pkgs/itcl4.0.5/generic/itclParse.c [moved from pkgs/itcl4.0.4/generic/itclParse.c with 99% similarity]
pkgs/itcl4.0.5/generic/itclResolve.c [moved from pkgs/itcl4.0.4/generic/itclResolve.c with 99% similarity]
pkgs/itcl4.0.5/generic/itclResolve2.c [moved from pkgs/itcl4.0.4/generic/itclResolve2.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclStubInit.c [moved from pkgs/itcl4.0.4/generic/itclStubInit.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclStubLib.c [moved from pkgs/itcl4.0.4/generic/itclStubLib.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclStubs.c [moved from pkgs/itcl4.0.4/generic/itclStubs.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclTclIntStubsFcn.c [moved from pkgs/itcl4.0.4/generic/itclTclIntStubsFcn.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclTclIntStubsFcn.h [moved from pkgs/itcl4.0.4/generic/itclTclIntStubsFcn.h with 100% similarity]
pkgs/itcl4.0.5/generic/itclTestRegisterC.c [moved from pkgs/itcl4.0.4/generic/itclTestRegisterC.c with 96% similarity]
pkgs/itcl4.0.5/generic/itclUtil.c [moved from pkgs/itcl4.0.4/generic/itclUtil.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclVCInt.h [moved from pkgs/itcl4.0.4/generic/itclVCInt.h with 100% similarity]
pkgs/itcl4.0.5/generic/itclVarsAndCmds.c [moved from pkgs/itcl4.0.4/generic/itclVarsAndCmds.c with 100% similarity]
pkgs/itcl4.0.5/generic/itclVarsAndCmds.h [moved from pkgs/itcl4.0.4/generic/itclVarsAndCmds.h with 100% similarity]
pkgs/itcl4.0.5/itclConfig.sh.in [moved from pkgs/itcl4.0.4/itclConfig.sh.in with 100% similarity]
pkgs/itcl4.0.5/library/itcl.tcl [moved from pkgs/itcl4.0.4/library/itcl.tcl with 100% similarity]
pkgs/itcl4.0.5/library/itclHullCmds.tcl [moved from pkgs/itcl4.0.4/library/itclHullCmds.tcl with 100% similarity]
pkgs/itcl4.0.5/library/itclWidget.tcl [moved from pkgs/itcl4.0.4/library/itclWidget.tcl with 100% similarity]
pkgs/itcl4.0.5/library/test_Itcl_CreateObject.tcl [moved from pkgs/itcl4.0.4/library/test_Itcl_CreateObject.tcl with 100% similarity]
pkgs/itcl4.0.5/license.terms [moved from pkgs/itcl4.0.4/license.terms with 100% similarity]
pkgs/itcl4.0.5/pkgIndex.tcl.in [moved from pkgs/itcl4.0.4/pkgIndex.tcl.in with 100% similarity]
pkgs/itcl4.0.5/releasenotes.txt [moved from pkgs/itcl4.0.4/releasenotes.txt with 100% similarity]
pkgs/itcl4.0.5/tclconfig/install-sh [moved from pkgs/thread2.7.3/tclconfig/install-sh with 100% similarity]
pkgs/itcl4.0.5/tclconfig/tcl.m4 [moved from pkgs/itcl4.0.4/tclconfig/tcl.m4 with 97% similarity]
pkgs/itcl4.0.5/tests/all.tcl [moved from pkgs/itcl4.0.4/tests/all.tcl with 100% similarity]
pkgs/itcl4.0.5/tests/basic.test [moved from pkgs/itcl4.0.4/tests/basic.test with 100% similarity]
pkgs/itcl4.0.5/tests/body.test [moved from pkgs/itcl4.0.4/tests/body.test with 100% similarity]
pkgs/itcl4.0.5/tests/chain.test [moved from pkgs/itcl4.0.4/tests/chain.test with 100% similarity]
pkgs/itcl4.0.5/tests/delete.test [moved from pkgs/itcl4.0.4/tests/delete.test with 100% similarity]
pkgs/itcl4.0.5/tests/eclasscomponent.test [moved from pkgs/itcl4.0.4/tests/eclasscomponent.test with 100% similarity]
pkgs/itcl4.0.5/tests/ensemble.test [moved from pkgs/itcl4.0.4/tests/ensemble.test with 100% similarity]
pkgs/itcl4.0.5/tests/general1.test [moved from pkgs/itcl4.0.4/tests/general1.test with 100% similarity]
pkgs/itcl4.0.5/tests/import.test [moved from pkgs/itcl4.0.4/tests/import.test with 100% similarity]
pkgs/itcl4.0.5/tests/info.test [moved from pkgs/itcl4.0.4/tests/info.test with 100% similarity]
pkgs/itcl4.0.5/tests/inherit.test [moved from pkgs/itcl4.0.4/tests/inherit.test with 100% similarity]
pkgs/itcl4.0.5/tests/interp.test [moved from pkgs/itcl4.0.4/tests/interp.test with 100% similarity]
pkgs/itcl4.0.5/tests/local.test [moved from pkgs/itcl4.0.4/tests/local.test with 100% similarity]
pkgs/itcl4.0.5/tests/methods.test [moved from pkgs/itcl4.0.4/tests/methods.test with 100% similarity]
pkgs/itcl4.0.5/tests/mkindex.itcl [moved from pkgs/itcl4.0.4/tests/mkindex.itcl with 100% similarity]
pkgs/itcl4.0.5/tests/mkindex.test [moved from pkgs/itcl4.0.4/tests/mkindex.test with 100% similarity]
pkgs/itcl4.0.5/tests/namespace.test [moved from pkgs/itcl4.0.4/tests/namespace.test with 100% similarity]
pkgs/itcl4.0.5/tests/protection.test [moved from pkgs/itcl4.0.4/tests/protection.test with 100% similarity]
pkgs/itcl4.0.5/tests/scope.test [moved from pkgs/itcl4.0.4/tests/scope.test with 100% similarity]
pkgs/itcl4.0.5/tests/sfbugs.test [moved from pkgs/itcl4.0.4/tests/sfbugs.test with 100% similarity]
pkgs/itcl4.0.5/tests/tclIndex [moved from pkgs/itcl4.0.4/tests/tclIndex with 100% similarity]
pkgs/itcl4.0.5/tests/typeclass.test [moved from pkgs/itcl4.0.4/tests/typeclass.test with 97% similarity]
pkgs/itcl4.0.5/tests/typedelegation.test [moved from pkgs/itcl4.0.4/tests/typedelegation.test with 100% similarity]
pkgs/itcl4.0.5/tests/typefunction.test [moved from pkgs/itcl4.0.4/tests/typefunction.test with 100% similarity]
pkgs/itcl4.0.5/tests/typeinfo.test [moved from pkgs/itcl4.0.4/tests/typeinfo.test with 100% similarity]
pkgs/itcl4.0.5/tests/typeoption.test [moved from pkgs/itcl4.0.4/tests/typeoption.test with 100% similarity]
pkgs/itcl4.0.5/tests/typevariable.test [moved from pkgs/itcl4.0.4/tests/typevariable.test with 100% similarity]
pkgs/itcl4.0.5/tests/widgetadaptor.test [moved from pkgs/itcl4.0.4/tests/widgetadaptor.test with 100% similarity]
pkgs/itcl4.0.5/tests/widgetclass.test [moved from pkgs/itcl4.0.4/tests/widgetclass.test with 100% similarity]
pkgs/itcl4.0.5/tools/genStubs.tcl [moved from pkgs/itcl4.0.4/tools/genStubs.tcl with 100% similarity]
pkgs/itcl4.0.5/win/dllEntryPoint.c [moved from pkgs/itcl4.0.4/win/dllEntryPoint.c with 100% similarity]
pkgs/itcl4.0.5/win/itcl.rc [moved from pkgs/itcl4.0.4/win/itcl.rc with 100% similarity]
pkgs/itcl4.0.5/win/makefile.vc [moved from pkgs/itcl4.0.4/win/makefile.vc with 100% similarity]
pkgs/itcl4.0.5/win/nmakehlp.c [moved from pkgs/itcl4.0.4/win/nmakehlp.c with 100% similarity]
pkgs/itcl4.0.5/win/rules.vc [moved from pkgs/itcl4.0.4/win/rules.vc with 100% similarity]
pkgs/itcl4.0.5/win/toaster.bmp [moved from pkgs/itcl4.0.4/win/toaster.bmp with 100% similarity]
pkgs/sqlite3.13.0/Makefile.in [moved from pkgs/sqlite3.11.0/Makefile.in with 100% similarity]
pkgs/sqlite3.13.0/README [moved from pkgs/sqlite3.11.0/README with 100% similarity]
pkgs/sqlite3.13.0/aclocal.m4 [moved from pkgs/sqlite3.11.0/aclocal.m4 with 100% similarity]
pkgs/sqlite3.13.0/compat/sqlite3/shell.c [moved from pkgs/sqlite3.11.0/compat/sqlite3/shell.c with 85% similarity]
pkgs/sqlite3.13.0/compat/sqlite3/spaceanal.tcl [moved from pkgs/sqlite3.11.0/compat/sqlite3/spaceanal.tcl with 98% similarity]
pkgs/sqlite3.13.0/compat/sqlite3/sqlite3.c [moved from pkgs/sqlite3.11.0/compat/sqlite3/sqlite3.c with 92% similarity]
pkgs/sqlite3.13.0/compat/sqlite3/sqlite3.h [moved from pkgs/sqlite3.11.0/compat/sqlite3/sqlite3.h with 85% similarity]
pkgs/sqlite3.13.0/compat/sqlite3/sqlite3ext.h [moved from pkgs/sqlite3.11.0/compat/sqlite3/sqlite3ext.h with 99% similarity]
pkgs/sqlite3.13.0/configure [moved from pkgs/sqlite3.11.0/configure with 98% similarity]
pkgs/sqlite3.13.0/configure.ac [moved from pkgs/sqlite3.11.0/configure.ac with 97% similarity]
pkgs/sqlite3.13.0/doc/sqlite3.n [moved from pkgs/sqlite3.11.0/doc/sqlite3.n with 100% similarity]
pkgs/sqlite3.13.0/generic/tclsqlite3.c [moved from pkgs/sqlite3.11.0/generic/tclsqlite3.c with 94% similarity]
pkgs/sqlite3.13.0/license.terms [moved from pkgs/sqlite3.11.0/license.terms with 100% similarity]
pkgs/sqlite3.13.0/pkgIndex.tcl.in [moved from pkgs/sqlite3.11.0/pkgIndex.tcl.in with 100% similarity]
pkgs/sqlite3.13.0/tclconfig/install-sh [moved from pkgs/sqlite3.11.0/tclconfig/install-sh with 100% similarity]
pkgs/sqlite3.13.0/tclconfig/tcl.m4 [moved from pkgs/thread2.7.3/tclconfig/tcl.m4 with 100% similarity]
pkgs/sqlite3.13.0/tests/all.tcl [moved from pkgs/sqlite3.11.0/tests/all.tcl with 100% similarity]
pkgs/sqlite3.13.0/tests/leapsecond.test [moved from pkgs/sqlite3.11.0/tests/leapsecond.test with 100% similarity]
pkgs/sqlite3.13.0/win/makefile.vc [moved from pkgs/sqlite3.11.0/win/makefile.vc with 100% similarity]
pkgs/sqlite3.13.0/win/nmakehlp.c [moved from pkgs/thread2.7.3/win/nmakehlp.c with 100% similarity]
pkgs/sqlite3.13.0/win/rules.vc [moved from pkgs/sqlite3.11.0/win/rules.vc with 100% similarity]
pkgs/thread2.7.3/configure [deleted file]
pkgs/thread2.7.3/doc/html/thread.html [deleted file]
pkgs/thread2.7.3/doc/html/tpool.html [deleted file]
pkgs/thread2.7.3/doc/html/tsv.html [deleted file]
pkgs/thread2.7.3/doc/html/ttrace.html [deleted file]
pkgs/thread2.7.3/doc/man/tpool.n [deleted file]
pkgs/thread2.7.3/tests/tsv.test [deleted file]
pkgs/thread2.8.0/ChangeLog [moved from pkgs/thread2.7.3/ChangeLog with 96% similarity]
pkgs/thread2.8.0/Makefile.in [moved from pkgs/thread2.7.3/Makefile.in with 100% similarity]
pkgs/thread2.8.0/README [moved from pkgs/thread2.7.3/README with 89% similarity]
pkgs/thread2.8.0/aclocal.m4 [moved from pkgs/thread2.7.3/aclocal.m4 with 50% similarity]
pkgs/thread2.8.0/configure [new file with mode: 0755]
pkgs/thread2.8.0/configure.ac [moved from pkgs/thread2.7.3/configure.ac with 95% similarity]
pkgs/thread2.8.0/doc/format.tcl [moved from pkgs/thread2.7.3/doc/format.tcl with 100% similarity]
pkgs/thread2.8.0/doc/html/thread.html [new file with mode: 0644]
pkgs/thread2.8.0/doc/html/tpool.html [new file with mode: 0644]
pkgs/thread2.8.0/doc/html/tsv.html [new file with mode: 0644]
pkgs/thread2.8.0/doc/html/ttrace.html [new file with mode: 0644]
pkgs/thread2.8.0/doc/man.macros [moved from pkgs/thread2.7.3/doc/man.macros with 100% similarity]
pkgs/thread2.8.0/doc/man/thread.n [moved from pkgs/thread2.7.3/doc/man/thread.n with 51% similarity]
pkgs/thread2.8.0/doc/man/tpool.n [new file with mode: 0644]
pkgs/thread2.8.0/doc/man/tsv.n [moved from pkgs/thread2.7.3/doc/man/tsv.n with 54% similarity]
pkgs/thread2.8.0/doc/man/ttrace.n [moved from pkgs/thread2.7.3/doc/man/ttrace.n with 52% similarity]
pkgs/thread2.8.0/doc/thread.man [moved from pkgs/thread2.7.3/doc/thread.man with 83% similarity]
pkgs/thread2.8.0/doc/tpool.man [moved from pkgs/thread2.7.3/doc/tpool.man with 93% similarity]
pkgs/thread2.8.0/doc/tsv.man [moved from pkgs/thread2.7.3/doc/tsv.man with 91% similarity]
pkgs/thread2.8.0/doc/ttrace.man [moved from pkgs/thread2.7.3/doc/ttrace.man with 89% similarity]
pkgs/thread2.8.0/generic/psGdbm.c [moved from pkgs/thread2.7.3/generic/psGdbm.c with 99% similarity]
pkgs/thread2.8.0/generic/psGdbm.h [moved from pkgs/thread2.7.3/generic/psGdbm.h with 100% similarity]
pkgs/thread2.8.0/generic/psLmdb.c [new file with mode: 0644]
pkgs/thread2.8.0/generic/psLmdb.h [new file with mode: 0644]
pkgs/thread2.8.0/generic/tclThread.h [moved from pkgs/thread2.7.3/generic/tclThread.h with 100% similarity]
pkgs/thread2.8.0/generic/tclThreadInt.h [moved from pkgs/thread2.7.3/generic/tclThreadInt.h with 98% similarity]
pkgs/thread2.8.0/generic/tclXkeylist.c [moved from pkgs/thread2.7.3/generic/tclXkeylist.c with 98% similarity]
pkgs/thread2.8.0/generic/tclXkeylist.h [moved from pkgs/thread2.7.3/generic/tclXkeylist.h with 100% similarity]
pkgs/thread2.8.0/generic/threadCmd.c [moved from pkgs/thread2.7.3/generic/threadCmd.c with 97% similarity]
pkgs/thread2.8.0/generic/threadNs.c [moved from pkgs/thread2.7.3/generic/threadNs.c with 97% similarity]
pkgs/thread2.8.0/generic/threadPoolCmd.c [moved from pkgs/thread2.7.3/generic/threadPoolCmd.c with 100% similarity]
pkgs/thread2.8.0/generic/threadSpCmd.c [moved from pkgs/thread2.7.3/generic/threadSpCmd.c with 98% similarity]
pkgs/thread2.8.0/generic/threadSpCmd.h [moved from pkgs/thread2.7.3/generic/threadSpCmd.h with 98% similarity]
pkgs/thread2.8.0/generic/threadSvCmd.c [moved from pkgs/thread2.7.3/generic/threadSvCmd.c with 94% similarity]
pkgs/thread2.8.0/generic/threadSvCmd.h [moved from pkgs/thread2.7.3/generic/threadSvCmd.h with 99% similarity]
pkgs/thread2.8.0/generic/threadSvKeylistCmd.c [moved from pkgs/thread2.7.3/generic/threadSvKeylistCmd.c with 100% similarity]
pkgs/thread2.8.0/generic/threadSvKeylistCmd.h [moved from pkgs/thread2.7.3/generic/threadSvKeylistCmd.h with 100% similarity]
pkgs/thread2.8.0/generic/threadSvListCmd.c [moved from pkgs/thread2.7.3/generic/threadSvListCmd.c with 100% similarity]
pkgs/thread2.8.0/generic/threadSvListCmd.h [moved from pkgs/thread2.7.3/generic/threadSvListCmd.h with 100% similarity]
pkgs/thread2.8.0/lib/ttrace.tcl [moved from pkgs/thread2.7.3/lib/ttrace.tcl with 99% similarity]
pkgs/thread2.8.0/license.terms [moved from pkgs/thread2.7.3/license.terms with 98% similarity]
pkgs/thread2.8.0/naviserver.m4 [moved from pkgs/thread2.7.3/naviserver.m4 with 100% similarity]
pkgs/thread2.8.0/pkgIndex.tcl.in [moved from pkgs/thread2.7.3/pkgIndex.tcl.in with 100% similarity]
pkgs/thread2.8.0/tcl/README [moved from pkgs/thread2.7.3/tcl/README with 60% similarity]
pkgs/thread2.8.0/tcl/cmdsrv/cmdsrv.tcl [moved from pkgs/thread2.7.3/tcl/cmdsrv/cmdsrv.tcl with 95% similarity]
pkgs/thread2.8.0/tcl/phttpd/index.htm [moved from pkgs/thread2.7.3/tcl/phttpd/index.htm with 100% similarity]
pkgs/thread2.8.0/tcl/phttpd/phttpd.tcl [moved from pkgs/thread2.7.3/tcl/phttpd/phttpd.tcl with 99% similarity]
pkgs/thread2.8.0/tcl/phttpd/uhttpd.tcl [moved from pkgs/thread2.7.3/tcl/phttpd/uhttpd.tcl with 98% similarity]
pkgs/thread2.8.0/tcl/tpool/tpool.tcl [moved from pkgs/thread2.7.3/tcl/tpool/tpool.tcl with 97% similarity]
pkgs/thread2.8.0/tclconfig/install-sh [moved from pkgs/itcl4.0.4/tclconfig/install-sh with 100% similarity]
pkgs/thread2.8.0/tclconfig/tcl.m4 [moved from pkgs/sqlite3.11.0/tclconfig/tcl.m4 with 100% similarity]
pkgs/thread2.8.0/tests/French.txt [new file with mode: 0644]
pkgs/thread2.8.0/tests/all.tcl [moved from pkgs/thread2.7.3/tests/all.tcl with 100% similarity]
pkgs/thread2.8.0/tests/store-load.tcl [new file with mode: 0644]
pkgs/thread2.8.0/tests/thread.test [moved from pkgs/thread2.7.3/tests/thread.test with 98% similarity]
pkgs/thread2.8.0/tests/tkt-84be1b5a73.test [new file with mode: 0644]
pkgs/thread2.8.0/tests/tpool.test [moved from pkgs/thread2.7.3/tests/tpool.test with 100% similarity]
pkgs/thread2.8.0/tests/tsv.test [new file with mode: 0644]
pkgs/thread2.8.0/tests/ttrace.test [moved from pkgs/thread2.7.3/tests/ttrace.test with 100% similarity]
pkgs/thread2.8.0/unix/CONFIG [moved from pkgs/thread2.7.3/unix/CONFIG with 96% similarity]
pkgs/thread2.8.0/unix/README [moved from pkgs/thread2.7.3/unix/README with 98% similarity]
pkgs/thread2.8.0/unix/threadUnix.c [moved from pkgs/thread2.7.3/unix/threadUnix.c with 100% similarity]
pkgs/thread2.8.0/win/CONFIG [moved from pkgs/thread2.7.3/win/CONFIG with 99% similarity]
pkgs/thread2.8.0/win/README.txt [moved from pkgs/thread2.7.3/win/README.txt with 94% similarity]
pkgs/thread2.8.0/win/makefile.vc [moved from pkgs/thread2.7.3/win/makefile.vc with 100% similarity]
pkgs/thread2.8.0/win/nmakehlp.c [moved from pkgs/sqlite3.11.0/win/nmakehlp.c with 100% similarity]
pkgs/thread2.8.0/win/pkg.vc [moved from pkgs/thread2.7.3/win/pkg.vc with 66% similarity]
pkgs/thread2.8.0/win/rules.vc [moved from pkgs/thread2.7.3/win/rules.vc with 100% similarity]
pkgs/thread2.8.0/win/thread.rc [moved from pkgs/thread2.7.3/win/thread.rc with 100% similarity]
pkgs/thread2.8.0/win/threadWin.c [moved from pkgs/thread2.7.3/win/threadWin.c with 100% similarity]
pkgs/thread2.8.0/win/thread_win.dsp [moved from pkgs/thread2.7.3/win/thread_win.dsp with 94% similarity]
pkgs/thread2.8.0/win/thread_win.dsw [moved from pkgs/thread2.7.3/win/thread_win.dsw with 100% similarity]
tests/assemble.test
tests/chanio.test
tests/cmdAH.test
tests/compile.test
tests/dict.test
tests/env.test
tests/event.test
tests/exec.test
tests/fileName.test
tests/history.test
tests/info.test
tests/interp.test
tests/io.test
tests/load.test
tests/lreplace.test
tests/msgcat.test
tests/namespace-old.test
tests/namespace.test
tests/oo.test
tests/parseOld.test
tests/registry.test
tests/resolver.test
tests/safe.test
tests/set-old.test
tests/set.test
tests/socket.test
tests/stringComp.test
tests/tcltest.test
tests/unload.test
tests/uplevel.test
tests/utf.test
tests/var.test
tests/zlib.test
tools/genStubs.tcl
tools/man2html.tcl
tools/man2html1.tcl
tools/man2html2.tcl
tools/tclZIC.tcl
tools/tcltk-man2html.tcl
unix/Makefile.in
unix/configure
unix/configure.in
unix/installManPage
unix/tcl.spec
unix/tclUnixNotfy.c
win/Makefile.in
win/coffbase.txt
win/configure
win/configure.in
win/makefile.vc
win/tclWinFile.c
win/tclWinInt.h
win/tclWinPipe.c
win/tclWinPort.h
win/tclWinReg.c
win/tclWinSock.c
win/tclWinThrd.c

diff --git a/README b/README
index f3e50dd..401b6e6 100644 (file)
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 README:  Tcl
-    This is the Tcl 8.6.5 source distribution.
+    This is the Tcl 8.6.6 source distribution.
        http://sourceforge.net/projects/tcl/files/Tcl/
     You can get any source release of Tcl from the URL above.
 
diff --git a/changes b/changes
index 1e24269..034380b 100644 (file)
--- a/changes
+++ b/changes
@@ -8624,3 +8624,77 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
 2016-02-22 (bug)[9b4702] [info exists env(missing)] kills trace (nijtmans)
 
 --- Released 8.6.5, February 29, 2016 --- http://core.tcl.tk/tcl/ for details
+
+2016-03-01 (bug)[803042] mem leak due to reference cycle (porter)
+
+2016-03-08 (bug)[bbc304] reflected watch race condition (porter)
+
+2016-03-17 (bug)[fadc99] compile-5.3 (rodriguez,porter)
+
+2016-03-17 (enhancement)[1a25fd] compile [variable ${ns}::v] (porter)
+
+2016-03-20 (bug)[1af8de] crash in compiled [string replace] (harder,fellows)
+
+2016-03-21 (bug)[d30718] segv in notifier finalize (hirofumi,nijtmans)
+
+2016-03-23 (enhancement)[7d0db7] parallel make (yarda,nijtmans)
+
+2016-03-23 [f12535] enable test bindings customization (vogel,nijtmans)
+
+2016-04-04 (bug)[47ac84] compiled [lreplace] fixes (aspect,ferrieux,fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-04-08 (bug)[866368] RE \w includes 'Punctuation Connector' (nijtmans)
+
+2016-04-08 (bug)[2538f3] Win crash Tcl_OpenTcpServer() (griffin)
+
+2016-04-10 [07d13d] Restore TclBlend support lost in 8.6.1 (buratti)
+
+2016-05-13 (bug)[3154ea] Mem corruption in assembler exceptions (tkob,kenny)
+
+2016-05-13 (bug) registry package support any Unicode env (nijtmans)
+=> registry 1.3.2
+
+2016-05-21 (bug)[f7d4e] [namespace delete] performance (fellows)
+
+2016-06-02 (TIP 447) execution time verbosity option (cerutti)
+=> tcltest 2.4.0
+
+2016-06-16 (bug)[16828b] crash due to [vwait] trace undo fail (dah,porter)
+
+2016-06-16 (enhancement)[4b61af] good [info frame] from more cases (beric)
+
+2016-06-21 (bug)[c383eb] crash in [glob -path a] (oehlmann,porter)
+
+2016-06-21 (update) Update Unicode data to 9.0 (nijtmans)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-06-22 (bug)[16896d] Tcl_DString tolerate append to self. (dah,porter)
+
+2016-06-23 (bug)[d55322] crash in [dict update] (yorick,fellows)
+
+2016-06-27 (bug)[dd260a] crash in [chan configure -dictionary] (madden,aspect)
+
+2016-07-02 (bug)[f961d7] usage message with parameters with spaces (porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-02 (enhancement)[09fabc] Sort order of -relateddir (lanam)
+
+2016-07-07 (bug)[5d7ca0] Win: [file executable] for .cmd and .ps1 (nadkarni)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-08 (bug)[a47641] [file normalize] & Windows junctions (nadkarni)
+
+2016-07-09 [ae61a6] [file] handling of Win hardcoded names (CON) (nadkarni)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-09 [3613671] [file owned] (more) useful on Win (nadkarni)
+
+2016-07-09 (bug)[1493a4] [namespace upvar] use of resolvers (beric,fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-10 (bug)[da340d] integer division in clock math (nadkarni)
+
+2016-07-20 tzdata updated to Olson's tzdata2016f (venkat)
+
+--- Released 8.6.6, July 27, 2016 --- http://core.tcl.tk/tcl/ for details
index 668e1db..699d7ed 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
index e6563a0..caba125 100644 (file)
@@ -17,7 +17,7 @@ Tcl_GetReturnOptions, Tcl_SetReturnOptions, Tcl_AddErrorInfo, Tcl_AppendObjToErr
 Tcl_Obj *
 \fBTcl_GetReturnOptions\fR(\fIinterp, code\fR)
 .sp
-int 
+int
 \fBTcl_SetReturnOptions\fR(\fIinterp, options\fR)
 .sp
 \fBTcl_AddErrorInfo\fR(\fIinterp, message\fR)
@@ -45,7 +45,7 @@ void
 .AS Tcl_Interp commandLength
 .AP Tcl_Interp *interp in
 Interpreter in which to record information.
-.AP int code 
+.AP int code
 The code returned from script evaluation.
 .AP Tcl_Obj *options
 A dictionary of return options.
@@ -121,7 +121,7 @@ retrieve the stack trace when script evaluation returns
 .CS
 int code = Tcl_Eval(interp, script);
 if (code == TCL_ERROR) {
-    Tcl_Obj *options = \fBTcl_GetReturnOptions\fR(interp, code);  
+    Tcl_Obj *options = \fBTcl_GetReturnOptions\fR(interp, code);
     Tcl_Obj *key = Tcl_NewStringObj("-errorinfo", -1);
     Tcl_Obj *stackTrace;
     Tcl_IncrRefCount(key);
@@ -163,12 +163,12 @@ to any reference counting.  This is analogous to
 .PP
 While \fBTcl_SetReturnOptions\fR provides a general interface
 to set any collection of return options, there are a handful
-of return options that are very frequently used.  Most 
+of return options that are very frequently used.  Most
 notably the \fB\-errorinfo\fR and \fB\-errorcode\fR return
 options should be set properly when the command procedure
 of a command returns \fBTCL_ERROR\fR.  The \fB\-errorline\fR
 return option is also read by commands that evaluate scripts
-and wish to supply detailed error location information in 
+and wish to supply detailed error location information in
 the stack trace text they append to the \fB\-errorinfo\fR option.
 Tcl provides several simpler interfaces to more directly set
 these return options.
@@ -224,7 +224,7 @@ is available as a \fBTcl_Obj\fR instead of as a \fBchar\fR array.
 .PP
 \fBTcl_AddObjErrorInfo\fR is nearly identical
 to \fBTcl_AddErrorInfo\fR, except that it has an additional \fIlength\fR
-argument.  This allows the \fImessage\fR string to contain 
+argument.  This allows the \fImessage\fR string to contain
 embedded null bytes.  This is essentially never a good idea.
 If the \fImessage\fR needs to contain the null character \fBU+0000\fR,
 Tcl's usual internal encoding rules should be used to avoid
@@ -232,9 +232,9 @@ the need for a null byte.  If the \fBTcl_AddObjErrorInfo\fR
 interface is used at all, it should be with a negative \fIlength\fR value.
 .PP
 The procedure \fBTcl_SetObjErrorCode\fR is used to set the
-\fB\-errorcode\fR return option to the list value \fIerrorObjPtr\fR 
-built up by the caller. 
-\fBTcl_SetObjErrorCode\fR is typically invoked just 
+\fB\-errorcode\fR return option to the list value \fIerrorObjPtr\fR
+built up by the caller.
+\fBTcl_SetObjErrorCode\fR is typically invoked just
 before returning an error. If an error is
 returned without calling \fBTcl_SetObjErrorCode\fR or
 \fBTcl_SetErrorCode\fR the Tcl interpreter automatically sets
@@ -275,7 +275,7 @@ the interpreter's result.
 \fBTcl_LogCommandInfo\fR is invoked after an error occurs in an
 interpreter.  It adds information about the command that was being
 executed when the error occurred to the \fB\-errorinfo\fR value, and
-the line number stored internally in the interpreter is set.  
+the line number stored internally in the interpreter is set.
 .PP
 In older releases of Tcl, there was no \fBTcl_GetReturnOptions\fR
 routine.  In its place, the global Tcl variables \fBerrorInfo\fR
@@ -288,7 +288,7 @@ global variables remains a supported way to access these
 return option values, it is important not to assume that
 writing to those global variables will properly set the
 corresponding return options.  It has long been emphasized
-in this manual page that it is important to 
+in this manual page that it is important to
 call the procedures described here rather than
 setting \fBerrorInfo\fR or \fBerrorCode\fR directly with
 \fBTcl_ObjSetVar2\fR.
@@ -297,7 +297,7 @@ If the procedure \fBTcl_ResetResult\fR is called,
 it clears all of the state of the interpreter associated with
 script evaluation, including the entire return options dictionary.
 In particular, the \fB\-errorinfo\fR and \fB\-errorcode\fR options
-are reset.  
+are reset.
 If an error had occurred, the \fBTcl_ResetResult\fR call will
 clear the error state to make it appear as if no error had
 occurred after all.
index 585704a..8f25c52 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Alloc 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
index 2343e66..172bb30 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_AllowExceptions 3 7.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -31,7 +31,7 @@ return with an appropriate message.  The particular script
 evaluation procedures of Tcl that act in the manner are
 \fBTcl_EvalObjEx\fR, \fBTcl_EvalObjv\fR, \fBTcl_Eval\fR, \fBTcl_EvalEx\fR,
 \fBTcl_GlobalEval\fR, \fBTcl_GlobalEvalObj\fR, \fBTcl_VarEval\fR and
-\fBTcl_VarEvalVA\fR. 
+\fBTcl_VarEvalVA\fR.
 .PP
 However, if \fBTcl_AllowExceptions\fR is invoked immediately before
 calling one of those a procedures, then arbitrary completion
index 3e47c1f..44b2d6b 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_AppInit 3 7.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -52,7 +52,7 @@ Invoke a startup script to initialize the application.
 Use the routines \fBTcl_SetStartupScript\fR and
 \fBTcl_GetStartupScript\fR to set or query the file and encoding
 that the active \fBTcl_Main\fR or \fBTk_Main\fR routine will
-use as a startup script. 
+use as a startup script.
 .LP
 \fBTcl_AppInit\fR returns \fBTCL_OK\fR or \fBTCL_ERROR\fR.
 If it returns \fBTCL_ERROR\fR then it must leave an error message in
index f819acb..d4fa3d7 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_SetAssocData 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
index 558b511..347ba3d 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
index 4ebcb60..adbe33c 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_BackgroundError 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
index f121c7c..0805f8e 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Backslash 3 "8.1" Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -33,7 +33,7 @@ The use of \fBTcl_Backslash\fR is deprecated in favor of
 .PP
 This is a utility procedure provided for backwards compatibility with
 non-internationalized Tcl extensions.  It parses a backslash sequence and
-returns the low byte of the Unicode character corresponding to the sequence. 
+returns the low byte of the Unicode character corresponding to the sequence.
 \fBTcl_Backslash\fR modifies \fI*countPtr\fR to contain the number of
 characters in the backslash sequence.
 .PP
index 5c8414d..7268e1f 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_BooleanObj 3 8.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -50,7 +50,7 @@ value \fIboolValue\fR in it, and returns a pointer to the new Tcl_Obj.
 The new Tcl_Obj has reference count of zero.
 .PP
 \fBTcl_SetBooleanObj\fR accepts \fIobjPtr\fR, a pointer to
-an existing Tcl_Obj, and stores in the Tcl_Obj \fI*objPtr\fR 
+an existing Tcl_Obj, and stores in the Tcl_Obj \fI*objPtr\fR
 the boolean value \fIboolValue\fR.  This is a write operation
 on \fI*objPtr\fR, so \fIobjPtr\fR must be unshared.  Attempts to
 write to a shared Tcl_Obj will panic.  A successful write
@@ -61,7 +61,7 @@ any former value stored in \fI*objPtr\fR.
 from the value stored in \fI*objPtr\fR.
 If \fIobjPtr\fR holds a string value recognized by \fBTcl_GetBoolean\fR,
 then the recognized boolean value is written at the address given
-by \fIboolPtr\fR.  
+by \fIboolPtr\fR.
 If \fIobjPtr\fR holds any value recognized as
 a number by Tcl, then if that value is zero a 0 is written at
 the address given by \fIboolPtr\fR and if that
@@ -69,10 +69,10 @@ value is non-zero a 1 is written at the address given by \fIboolPtr\fR.
 In all cases where a value is written at the address given
 by \fIboolPtr\fR, \fBTcl_GetBooleanFromObj\fR returns \fBTCL_OK\fR.
 If the value of \fIobjPtr\fR does not meet any of the conditions
-above, then \fBTCL_ERROR\fR is returned and an error message is 
+above, then \fBTCL_ERROR\fR is returned and an error message is
 left in the interpreter's result unless \fIinterp\fR is NULL.
 \fBTcl_GetBooleanFromObj\fR may also make changes to the internal
-fields of \fI*objPtr\fR so that future calls to 
+fields of \fI*objPtr\fR so that future calls to
 \fBTcl_GetBooleanFromObj\fR on the same \fIobjPtr\fR can be
 performed more efficiently.
 .PP
index a1f9330..ff0b4e1 100644 (file)
@@ -3,12 +3,12 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
 .SH NAME
-Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl values as a arrays of bytes 
+Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl values as a arrays of bytes
 .SH SYNOPSIS
 .nf
 \fB#include <tcl.h>\fR
@@ -16,7 +16,7 @@ Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteAr
 Tcl_Obj *
 \fBTcl_NewByteArrayObj\fR(\fIbytes, length\fR)
 .sp
-void 
+void
 \fBTcl_SetByteArrayObj\fR(\fIobjPtr, bytes, length\fR)
 .sp
 unsigned char *
@@ -82,7 +82,7 @@ allocated for the array, the array is reallocated to the new length; the
 newly allocated bytes at the end of the array have arbitrary values.  If
 \fIlength\fR is less than the space currently allocated for the array,
 the length of array is reduced to the new length.  The return value is a
-pointer to the value's new array of bytes.  
+pointer to the value's new array of bytes.
 
 .SH "SEE ALSO"
 Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
index f6b1636..847707e 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Cancel 3 8.6 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -53,10 +53,10 @@ Any ORed combination of the following values may be used for the
 \fBTCL_CANCEL_UNWIND\fR
 .
 This flag is used by \fBTcl_CancelEval\fR and \fBTcl_Canceled\fR.
-For \fBTcl_CancelEval\fR, if this flag is set, the script in progress 
+For \fBTcl_CancelEval\fR, if this flag is set, the script in progress
 is canceled and the evaluation stack for the interpreter is unwound.
-For \fBTcl_Canceled\fR, if this flag is set, the script in progress 
-is considered to be canceled only if the evaluation stack for the 
+For \fBTcl_Canceled\fR, if this flag is set, the script in progress
+is considered to be canceled only if the evaluation stack for the
 interpreter is being unwound.
 .TP 20
 \fBTCL_LEAVE_ERR_MSG\fR
index 2335de1..6ef94b5 100644 (file)
@@ -639,13 +639,13 @@ called to set them, e.g. \fB\-blockmode\fR. Other options are specific to
 each channel type and the \fIsetOptionProc\fR procedure of the channel
 driver will get called to implement them. The \fIsetOptionProc\fR field can
 be NULL, which indicates that this channel type supports no type specific
-options. 
+options.
 .PP
 If the option value is successfully modified to the new value, the function
 returns \fBTCL_OK\fR.
 It should call \fBTcl_BadChannelOption\fR which itself returns
 \fBTCL_ERROR\fR if the \fIoptionName\fR is
-unrecognized. 
+unrecognized.
 If \fInewValue\fR specifies a value for the option that
 is not supported or if a system call error occurs,
 the function should leave an error message in the
@@ -674,7 +674,7 @@ channel. If the option name is not NULL, the function stores its current
 value, as a string, in the Tcl dynamic string \fIoptionValue\fR.
 If \fIoptionName\fR is NULL, the function stores in \fIoptionValue\fR an
 alternating list of all supported options and their current values.
-On success, the function returns \fBTCL_OK\fR. 
+On success, the function returns \fBTCL_OK\fR.
 It should call \fBTcl_BadChannelOption\fR which itself returns
 \fBTCL_ERROR\fR if the \fIoptionName\fR is
 unrecognized. If a system call error occurs,
@@ -839,7 +839,7 @@ which returns a pointer to the function.
 This procedure generates a
 .QW "bad option"
 error message in an
-(optional) interpreter.  It is used by channel drivers when 
+(optional) interpreter.  It is used by channel drivers when
 an invalid Set/Get option is requested. Its purpose is to concatenate
 the generic options list to the specific ones and factorize
 the generic options error message string.
@@ -850,7 +850,7 @@ An error message is generated in \fIinterp\fR's result value to
 indicate that a command was invoked with a bad option.
 The message has the form
 .CS
-    bad option "blah": should be one of 
+    bad option "blah": should be one of
     <...generic options...>+<...specific options...>
 .CE
 so you get for instance:
index fca64ce..bf76d48 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_CreateCommand 3 "" Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -91,7 +91,7 @@ the command, \fIargc\fR giving the number of arguments (including
 the command name) and \fIargv\fR giving the values of the arguments
 as strings.  The \fIargv\fR array will contain \fIargc\fR+1 values;
 the first \fIargc\fR values point to the argument strings, and the
-last value is NULL.  
+last value is NULL.
 Note that the argument strings should not be modified as they may
 point to constant strings or may be shared with other parts of the
 interpreter.
index 84cde65..acceb5b 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_CreateMathFunc 3 8.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -147,7 +147,7 @@ released by passing it to \fBTcl_Free\fR.  Some functions (the
 standard set implemented in the core, and those defined by placing
 commands in the \fBtcl::mathfunc\fR namespace) do not have
 argument type information; attempting to retrieve values for
-them causes a NULL to be stored in the variable pointed to by 
+them causes a NULL to be stored in the variable pointed to by
 \fIprocPtr\fR and the variable pointed to by \fIclientDataPtr\fR
 will not be modified.  The variable pointed to by \fInumArgsPointer\fR
 will contain -1, and no argument types will be stored in the variable
index e94c8cd..6714bd7 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -150,7 +150,7 @@ However, if the existing command was created by a previous call to
 but instead arranges for the Tcl interpreter to call the
 \fBTcl_ObjCmdProc\fR \fIproc\fR in the future.
 The old string-based \fBTcl_CmdProc\fR associated with the command
-is retained and its address can be obtained by subsequent 
+is retained and its address can be obtained by subsequent
 \fBTcl_GetCommandInfo\fR calls. This is done for backwards compatibility.
 .PP
 \fIDeleteProc\fR will be invoked when (if) \fIname\fR is deleted.
@@ -288,7 +288,7 @@ command is not deleted or renamed;  callers should copy the string if
 they need to keep it for a long time.
 .PP
 \fBTcl_GetCommandFullName\fR produces the fully qualified name
-of a command from a command token.  
+of a command from a command token.
 The name, including all namespace prefixes,
 is appended to the value specified by \fIobjPtr\fR.
 .PP
index fdcef6f..ac681bc 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_CreateSlave 3 7.6 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -122,8 +122,8 @@ is either \fBTCL_OK\fR or \fBTCL_ERROR\fR. If \fBTCL_ERROR\fR is returned
 then the \fBresult\fR field of the interpreter contains an error message.
 .PP
 \fBTcl_CreateSlave\fR creates a new interpreter as a slave of \fIinterp\fR.
-It also creates a slave command named \fIslaveName\fR in \fIinterp\fR which 
-allows \fIinterp\fR to manipulate the new slave. 
+It also creates a slave command named \fIslaveName\fR in \fIinterp\fR which
+allows \fIinterp\fR to manipulate the new slave.
 If \fIisSafe\fR is zero, the command creates a trusted slave in which Tcl
 code has access to all the Tcl commands.
 If it is \fB1\fR, the command creates a
@@ -178,7 +178,7 @@ created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
 \fItargetInterp\fR. Any two interpreters can be used, without any
 restrictions on how they are related.
 .PP
-\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except 
+\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
 that it takes a vector of values to pass as additional arguments instead
 of a vector of strings.
 .PP
@@ -196,7 +196,7 @@ strings.
 \fBTcl_ExposeCommand\fR moves the command named \fIhiddenCmdName\fR from
 the set of hidden commands to the set of exposed commands, putting
 it under the name
-\fIcmdName\fR. 
+\fIcmdName\fR.
 \fIHiddenCmdName\fR must be the name of an existing hidden
 command, or the operation will return \fBTCL_ERROR\fR and leave an error
 message in the \fIresult\fR field in \fIinterp\fR.
index 239941f..d5353ac 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_CreateTrace 3 "" Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -65,7 +65,7 @@ interpreter.
 \fBTcl_CmdObjTraceProc\fR:
 .PP
 .CS
-typedef int \fBTcl_CmdObjTraceProc\fR( 
+typedef int \fBTcl_CmdObjTraceProc\fR(
         \fBClientData\fR \fIclientData\fR,
         \fBTcl_Interp\fR* \fIinterp\fR,
         int \fIlevel\fR,
@@ -143,7 +143,7 @@ When \fBTcl_DeleteTrace\fR is called, the interpreter invokes the
 \fBTcl_CmdObjTraceDeleteProc\fR:
 .PP
 .CS
-typedef void \fBTcl_CmdObjTraceDeleteProc\fR( 
+typedef void \fBTcl_CmdObjTraceDeleteProc\fR(
         \fBClientData\fR \fIclientData\fR);
 .CE
 .PP
index 6f08b34..d48afd0 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_DoOneEvent 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -20,7 +20,7 @@ int
 .AS int flags
 .AP int flags in
 This parameter is normally zero.  It may be an OR-ed combination
-of any of the following flag bits:  
+of any of the following flag bits:
 \fBTCL_WINDOW_EVENTS\fR, \fBTCL_FILE_EVENTS\fR,
 \fBTCL_TIMER_EVENTS\fR, \fBTCL_IDLE_EVENTS\fR, \fBTCL_ALL_EVENTS\fR,
 or \fBTCL_DONT_WAIT\fR.
@@ -43,7 +43,7 @@ handlers for the first event on the queue, and returns.
 If no events are found, \fBTcl_DoOneEvent\fR checks for \fBTcl_DoWhenIdle\fR
 callbacks; if any are found, it invokes all of them and returns.
 Finally, if no events or idle callbacks have been found, then
-\fBTcl_DoOneEvent\fR sleeps until an event occurs; then it adds any 
+\fBTcl_DoOneEvent\fR sleeps until an event occurs; then it adds any
 new events to the Tcl event queue, calls handlers for the first event,
 and returns.
 The normal return value is 1 to signify that some event
index 4b422d4..85e4de5 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -28,7 +28,7 @@ A double-precision floating-point value used to initialize or set a Tcl value.
 For \fBTcl_SetDoubleObj\fR, this points to the value in which to store a
 double value.
 For \fBTcl_GetDoubleFromObj\fR, this refers to the value
-from which to retrieve a double value. 
+from which to retrieve a double value.
 .AP Tcl_Interp *interp in/out
 When non-NULL, an error message is left here when double value retrieval fails.
 .AP double *doublePtr out
@@ -56,7 +56,7 @@ returned, and the double value is written to the storage pointed to by
 \fIdoublePtr\fR.  If the attempt fails, then \fBTCL_ERROR\fR is returned,
 and if \fIinterp\fR is non-NULL, an error message is left in \fIinterp\fR.
 The \fBTcl_ObjType\fR of \fIobjPtr\fR may be changed to make subsequent
-calls to \fBTcl_GetDoubleFromObj\fR more efficient. 
+calls to \fBTcl_GetDoubleFromObj\fR more efficient.
 '\" TODO: add discussion of treatment of NaN value
 .SH "SEE ALSO"
 Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
index f4d78d1..43333da 100644 (file)
@@ -2,7 +2,7 @@
 '\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
 '\" Copyright (c) 2000 by Scriptics Corporation.
 '\" All rights reserved.
-'\" 
+'\"
 .TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -39,7 +39,7 @@ These functions provide access to Tcl memory debugging information.
 They are only functional when Tcl has been compiled with
 \fBTCL_MEM_DEBUG\fR defined at compile-time.  When \fBTCL_MEM_DEBUG\fR
 is not defined, these functions are all no-ops.
-.PP 
+.PP
 \fBTcl_DumpActiveMemory\fR will output a list of all currently
 allocated memory to the specified file.  The information output for
 each allocated block of memory is:  starting and ending addresses
index 8457ddc..30c1d3b 100644 (file)
@@ -3,9 +3,9 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 '\" This documents the C API introduced in TIP#235
-'\" 
+'\"
 .TH Tcl_Ensemble 3 8.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -185,7 +185,7 @@ the bound namespace. May be read and written using
 \fBTcl_GetEnsembleSubcommandList\fR and
 \fBTcl_SetEnsembleSubcommandList\fR respectively. The result of both
 of those functions is a Tcl result code (\fBTCL_OK\fR, or
-\fBTCL_ERROR\fR if the 
+\fBTCL_ERROR\fR if the
 token does not refer to an ensemble) and the list obtained from
 \fBTcl_GetEnsembleSubcommandList\fR should always be treated as
 immutable even if it is unshared.
index c104f7a..8661923 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Eval 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -116,7 +116,7 @@ of the words for the Tcl command, one word in each value in
 a completion code and result just like \fBTcl_EvalObjEx\fR.
 The caller of \fBTcl_EvalObjv\fR has to manage the reference count of the
 elements of \fIobjv\fR, insuring that the values are valid until
-\fBTcl_EvalObjv\fR returns.  
+\fBTcl_EvalObjv\fR returns.
 .PP
 \fBTcl_Eval\fR is similar to \fBTcl_EvalObjEx\fR except that the script to
 be executed is supplied as a string instead of a value and no compilation
@@ -127,7 +127,7 @@ might be a UTF-8 special code.  The string is parsed and executed directly
 (using \fBTcl_EvalObjv\fR) instead of compiling it and executing the
 bytecodes.  In situations where it is known that the script will never be
 executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
- \fBTcl_Eval\fR returns a completion code and result just like 
+ \fBTcl_Eval\fR returns a completion code and result just like
 \fBTcl_EvalObjEx\fR.  Note: for backward compatibility with versions before
 Tcl 8.0, \fBTcl_Eval\fR copies the value result in \fIinterp\fR to
 \fIinterp->result\fR (use is deprecated) where it can be accessed directly.
index 3ea09bf..9a04db3 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Exit 3 8.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -120,7 +120,7 @@ If extension \fBA\fR registers its exit handlers before loading extension
 \fBB\fR, this ensures that any exit handlers for \fBB\fR will be executed
 before the exit handlers for \fBA\fR.
 .PP
-\fBTcl_Finalize\fR and \fBTcl_Exit\fR call \fBTcl_FinalizeThread\fR 
+\fBTcl_Finalize\fR and \fBTcl_Exit\fR call \fBTcl_FinalizeThread\fR
 and the thread exit handlers \fIafter\fR
 the process-wide exit handlers.  This is because thread finalization shuts
 down the I/O channel system, so any attempt at I/O by the global exit
index 1615f88..0d369ce 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_ExprLong 3 7.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -30,7 +30,7 @@ int
 .AP Tcl_Interp *interp in
 Interpreter in whose context to evaluate \fIexpr\fR.
 .AP "const char" *expr in
-Expression to be evaluated.  
+Expression to be evaluated.
 .AP long *longPtr out
 Pointer to location in which to store the integer value of the
 expression.
index 6a8158c..28ee8f0 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Filesystem 3 8.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -464,8 +464,8 @@ directory for all files which match a given pattern. The appropriate
 function for the filesystem to which \fIpathPtr\fR belongs will be called.
 .PP
 The return value is a standard Tcl result indicating whether an error
-occurred in globbing. Error messages are placed in interp (unless 
-interp is NULL, which is allowed), but good results are placed in the 
+occurred in globbing. Error messages are placed in interp (unless
+interp is NULL, which is allowed), but good results are placed in the
 resultPtr given.
 .PP
 Note that the \fBglob\fR code implements recursive patterns internally, so
@@ -1256,8 +1256,8 @@ not, so code should be flexible to both possibilities.
 The return value is a standard Tcl result indicating whether an error
 occurred in the matching process. Error messages are placed in
 \fIinterp\fR, unless \fIinterp\fR in NULL in which case no error
-message need be generated; on a \fBTCL_OK\fR result, results should be 
-added to the \fIresultPtr\fR value given (which can be assumed to be a 
+message need be generated; on a \fBTCL_OK\fR result, results should be
+added to the \fIresultPtr\fR value given (which can be assumed to be a
 valid unshared Tcl list). The matches added
 to \fIresultPtr\fR should include any path prefix given in \fIpathPtr\fR
 (this usually means they will be absolute path specifications).
@@ -1265,7 +1265,7 @@ Note that if no matches are found, that simply leads to an empty
 result; errors are only signaled for actual file or filesystem
 problems which may occur during the matching process.
 .PP
-The \fBTcl_GlobTypeData\fR structure passed in the \fItypes\fR 
+The \fBTcl_GlobTypeData\fR structure passed in the \fItypes\fR
 parameter contains the following fields:
 .PP
 .CS
index 8aed0dc..73432d3 100644 (file)
@@ -1,7 +1,7 @@
 '\"
 '\" Copyright (c) 1998-2000 by Scriptics Corporation.
 '\" All rights reserved.
-'\" 
+'\"
 .TH Tcl_GetHostName 3 8.3 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -18,7 +18,7 @@ const char *
 .SH DESCRIPTION
 .PP
 \fBTcl_GetHostName\fR is a utility procedure used by some of the
-Tcl commands.  It returns a pointer to a string containing the name 
+Tcl commands.  It returns a pointer to a string containing the name
 for the current machine, or an empty string if the name cannot be
 determined.  The string is statically allocated, and the caller must
 not modify of free it.
index 8af1e7e..be0e79f 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_GetStdChannel 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -34,18 +34,18 @@ Tcl defines three special channels that are used by various I/O related
 commands if no other channels are specified.  The standard input channel
 has a channel name of \fBstdin\fR and is used by \fBread\fR and \fBgets\fR.
 The standard output channel is named \fBstdout\fR and is used by
-\fBputs\fR.  The standard error channel is named \fBstderr\fR and is used for 
+\fBputs\fR.  The standard error channel is named \fBstderr\fR and is used for
 reporting errors.  In addition, the standard channels are inherited by any
 child processes created using \fBexec\fR or \fBopen\fR in the absence of any
 other redirections.
 .PP
 The standard channels are actually aliases for other normal channels.  The
 current channel associated with a standard channel can be retrieved by calling
-\fBTcl_GetStdChannel\fR with one of 
+\fBTcl_GetStdChannel\fR with one of
 \fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, or \fBTCL_STDERR\fR as the \fItype\fR.  The
 return value will be a valid channel, or NULL.
 .PP
-A new channel can be set for the standard channel specified by \fItype\fR 
+A new channel can be set for the standard channel specified by \fItype\fR
 by calling \fBTcl_SetStdChannel\fR with a new channel or NULL in the
 \fIchannel\fR argument.  If the specified channel is closed by a later call to
 \fBTcl_Close\fR, then the corresponding standard channel will automatically be
@@ -64,7 +64,7 @@ be corrected without contradicting the assumptions of some existing
 code that calls \fBTcl_SetStdChannel\fR.
 .PP
 If \fBTcl_GetStdChannel\fR is called before \fBTcl_SetStdChannel\fR, Tcl will
-construct a new channel to wrap the appropriate platform-specific standard 
+construct a new channel to wrap the appropriate platform-specific standard
 file handle.  If \fBTcl_SetStdChannel\fR is called before
 \fBTcl_GetStdChannel\fR, then the default channel will not be created.
 .PP
index 89f63d5..3672382 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_GetVersion 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -24,14 +24,14 @@ Minor version number of the Tcl library.
 The patch level of the Tcl library (or alpha or beta number).
 .AP Tcl_ReleaseType *type out
 The type of release, also indicates the type of patch level. Can be
-one of \fBTCL_ALPHA_RELEASE\fR, \fBTCL_BETA_RELEASE\fR, or 
+one of \fBTCL_ALPHA_RELEASE\fR, \fBTCL_BETA_RELEASE\fR, or
 \fBTCL_FINAL_RELEASE\fR.
 .BE
 
 .SH DESCRIPTION
 .PP
 \fBTcl_GetVersion\fR should be used to query the version number
-of the Tcl library at runtime.  This is useful when using a 
+of the Tcl library at runtime.  This is useful when using a
 dynamically loaded Tcl library or when writing a stubs-aware
 extension.  For instance, if you write an extension that is
 linked against the Tcl stubs library, it could be loaded into
@@ -39,7 +39,7 @@ a program linked to an older version of Tcl than you expected.
 Use \fBTcl_GetVersion\fR to verify that fact, and possibly to
 change the behavior of your extension.
 .PP
-\fBTcl_GetVersion\fR accepts NULL for any of the arguments. For instance if 
+\fBTcl_GetVersion\fR accepts NULL for any of the arguments. For instance if
 you do not care about the \fIpatchLevel\fR of the library, pass
 a NULL for the \fIpatchLevel\fR argument.
 
index fcc0d83..4dc3623 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Hash 3 "" Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -131,13 +131,13 @@ The pointer value is the key;  it need not (and usually does not)
 actually point to a string.
 .IP \fBTCL_CUSTOM_TYPE_KEYS\fR 25
 Keys are of arbitrary type, and are stored in the entry. Hashing
-and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType 
-structure is described in the section 
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
 \fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
 .IP \fBTCL_CUSTOM_PTR_KEYS\fR 25
 Keys are pointers to an arbitrary type, and are stored in the entry. Hashing
-and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType 
-structure is described in the section 
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
 \fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
 .IP \fIother\fR 25
 If \fIkeyType\fR is not one of the above,
index d42b44a..dc62642 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -87,7 +87,7 @@ used to initialize a multi-precision integer value.
 .SH DESCRIPTION
 .PP
 These procedures are used to create, modify, and read Tcl values
-that hold integral values.  
+that hold integral values.
 .PP
 The different routines exist to accommodate different integral types in C
 with which values might be exchanged.  The C integral types for which Tcl
@@ -99,7 +99,7 @@ typedef defined to be whatever signed integral type covers at least the
 on the platform and the C compiler, the actual type might be
 \fBlong int\fR, \fBlong long int\fR, \fBint64\fR, or something else.
 The \fBmp_int\fR type is a multiple-precision integer type defined
-by the LibTomMath multiple-precision integer library.  
+by the LibTomMath multiple-precision integer library.
 .PP
 The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR,
 and \fBTcl_NewBignumObj\fR routines each create and return a new
index b639add..731007b 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Interp 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -76,7 +76,7 @@ and store a pointer to it in \fIinterp->result\fR.
 In this case, the command procedure must also set \fIinterp->freeProc\fR
 to the address of a procedure that can free the value, or \fBTCL_DYNAMIC\fR
 if the storage was allocated directly by Tcl or by a call to
-\fBTcl_Alloc\fR. 
+\fBTcl_Alloc\fR.
 If \fIinterp->freeProc\fR is non-zero, then Tcl will call \fIfreeProc\fR
 to free the space pointed to by \fIinterp->result\fR before it
 invokes the next command.
index 3af0e7e..dc1ba53 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -64,7 +64,7 @@ Points to location where \fBTcl_ListObjGetElements\fR
 stores the number of element values in \fIlistPtr\fR.
 .AP Tcl_Obj ***objvPtr out
 A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
-of pointers to the element values of \fIlistPtr\fR.  
+of pointers to the element values of \fIlistPtr\fR.
 .AP int objc in
 The number of Tcl values that \fBTcl_NewListObj\fR
 will insert into a new list value,
@@ -75,7 +75,7 @@ the number of Tcl values to insert into \fIobjPtr\fR.
 An array of pointers to values.
 \fBTcl_NewListObj\fR will insert these values into a new list value
 and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR.
-Each value will become a separate list element.  
+Each value will become a separate list element.
 .AP int *intPtr out
 Points to location where \fBTcl_ListObjLength\fR
 stores the length of the list.
@@ -134,7 +134,7 @@ If no error occurs,
 the two procedures return \fBTCL_OK\fR after appending the values.
 .PP
 \fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
-create a new value or modify an existing value to hold 
+create a new value or modify an existing value to hold
 the \fIobjc\fR elements of the array referenced by \fIobjv\fR
 where each element is a pointer to a Tcl value.
 If \fIobjc\fR is less than or equal to zero,
index a8ac477..ff0d108 100644 (file)
--- a/doc/NRE.3
+++ b/doc/NRE.3
@@ -3,7 +3,7 @@
 .\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH NRE 3 8.6 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -45,7 +45,7 @@ Name of a new command to create.
 Implementation of a command that will be called whenever \fIcmdName\fR
 is invoked as a command in the unoptimized way.
 .AP Tcl_ObjCmdProc *nreProc in
-Implementation of a command that will be called whenever \fIcmdName\fR 
+Implementation of a command that will be called whenever \fIcmdName\fR
 is invoked and requested to conserve the C stack.
 .AP ClientData clientData in
 Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
@@ -83,13 +83,13 @@ executing in the interpreter designated by \fIinterp\fR completes.
 to the function designated by \fIpostProcPtr\fR when it is invoked.
 .BE
 .SH DESCRIPTION
-.PP 
+.PP
 This series of C functions provides an interface whereby commands that
 are implemented in C can be evaluated, and invoke Tcl commands scripts
 and scripts, without consuming space on the C stack. The non-recursive
 evaluation is done by installing a \fItrampoline\fR, a small piece of
 code that invokes a command or script, and then executes a series of
-callbacks when the command or script returns. 
+callbacks when the command or script returns.
 .PP
 The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
 interpreter designated by \fIinterp\fR that is prepared to handle
@@ -149,7 +149,7 @@ The remaining arguments are as for \fBTcl_NREvalObjv\fR.
 \fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
 all accept a \fIflags\fR parameter, which is an OR-ed-together set of
 bits to control evaluation. At the present time, the only supported flag
-available to callers is \fBTCL_EVAL_GLOBAL\fR. 
+available to callers is \fBTCL_EVAL_GLOBAL\fR.
 .\" TODO: Again, this is a lie. Do we want to explain TCL_EVAL_INVOKE
 .\"       and TCL_EVAL_NOERR?
 If the \fBTCL_EVAL_GLOBAL\fR flag is set, the script or command is
@@ -255,7 +255,7 @@ int
     int objc,
     Tcl_Obj *const objv[])
 {
-    return \fBTcl_NRCallObjProc\fR(interp, \fITheCmdNRObjProc\fR, 
+    return \fBTcl_NRCallObjProc\fR(interp, \fITheCmdNRObjProc\fR,
             clientData, objc, objv);
 }
 .CE
index f2976b1..16f9f8d 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Notifier 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -143,7 +143,7 @@ servicing at a future time.  Threaded applications work in a
 similar manner, except that there is a separate event queue for
 each thread containing a Tcl interpreter.
 \fBTcl_QueueEvent\fR is used (primarily
-by event sources) to add events to the event queue and 
+by event sources) to add events to the event queue and
 \fBTcl_DeleteEvents\fR is used to remove events from the queue without
 processing them.  In a threaded application, \fBTcl_QueueEvent\fR adds
 an event to the current thread's queue, and \fBTcl_ThreadQueueEvent\fR
index 424d560..bf414ac 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -76,8 +76,8 @@ in that case \fBTCL_ERROR\fR is returned.
 if possible.
 It creates a new internal representation for \fIobjPtr\fR
 appropriate for the target type \fItypePtr\fR
-and sets its \fItypePtr\fR member as determined by calling the 
-\fItypePtr->setFromAnyProc\fR routine.  
+and sets its \fItypePtr\fR member as determined by calling the
+\fItypePtr->setFromAnyProc\fR routine.
 Any internal representation for \fIobjPtr\fR's old type is freed.
 If an error occurs during conversion, it returns \fBTCL_ERROR\fR
 and leaves an error message in the result value for \fIinterp\fR
@@ -181,7 +181,7 @@ typedef void \fBTcl_UpdateStringProc\fR(
 It must always set \fIbytes\fR non-NULL before returning.
 We require the string representation's byte array
 to have a null after the last byte, at offset \fIlength\fR,
-and to have no null bytes before that; this allows string representations 
+and to have no null bytes before that; this allows string representations
 to be treated as conventional null character-terminated C strings.
 These restrictions are easily met by using Tcl's internal UTF encoding
 for the string representation, same as one would do for other
index 28d56fa..af86665 100644 (file)
@@ -1,7 +1,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Panic 3 8.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -69,7 +69,7 @@ After \fBTcl_SetPanicProc\fR returns, any future calls to
 \fIformat\fR and \fIarg\fR arguments. \fIpanicProc\fR should avoid
 making calls into the Tcl library, or into other libraries that may
 call the Tcl library, since the original call to \fBTcl_Panic\fR
-indicates the Tcl library is not in a state of reliable operation.  
+indicates the Tcl library is not in a state of reliable operation.
 .PP
 The typical use of \fBTcl_SetPanicProc\fR arranges for the error message
 to be displayed or reported in a manner more suitable for the
index 5c9fdca..71f3acf 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -75,8 +75,8 @@ procedures do.
 .PP
 If \fBTcl_PkgPresent\fR or \fBTcl_PkgRequire\fR complete successfully
 they return a pointer to the version string for the version of the package
-that is provided in the interpreter (which may be different than 
-\fIversion\fR); if an error occurs they return NULL and leave an error 
+that is provided in the interpreter (which may be different than
+\fIversion\fR); if an error occurs they return NULL and leave an error
 message in the interpreter's result.
 .PP
 \fBTcl_PkgProvide\fR returns \fBTCL_OK\fR if it completes successfully;
index 63f650b..aa757bc 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_RegExpMatch 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -103,7 +103,7 @@ should be stored by \fBTcl_RegExpGetInfo\fR.
 \fBTcl_RegExpMatch\fR determines whether its \fIpattern\fR argument
 matches \fIregexp\fR, where \fIregexp\fR is interpreted
 as a regular expression using the rules in the \fBre_syntax\fR
-reference page. 
+reference page.
 If there is a match then \fBTcl_RegExpMatch\fR returns 1.
 If there is no match then \fBTcl_RegExpMatch\fR returns 0.
 If an error occurs in the matching process (e.g. \fIpattern\fR
@@ -111,7 +111,7 @@ is not a valid regular expression) then \fBTcl_RegExpMatch\fR
 returns \-1 and leaves an error message in the interpreter result.
 \fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
 operates on the Tcl values \fItextObj\fR and \fIpatObj\fR instead of
-UTF strings. 
+UTF strings.
 \fBTcl_RegExpMatchObj\fR is generally more efficient than
 \fBTcl_RegExpMatch\fR, so it is the preferred interface.
 .PP
@@ -201,7 +201,7 @@ Compile extended regular expressions
 .PQ ERE s .
 This mode corresponds
 to the regular expression syntax recognized by Tcl 8.0 and earlier
-versions. 
+versions.
 .TP
 \fBTCL_REG_BASIC\fR
 Compile basic regular expressions
@@ -375,7 +375,7 @@ character in the string where a match could occur.  If a match was
 found, this will be the same as the beginning of the current match.
 If no match was found, then it indicates the earliest point at which a
 match might occur if additional text is appended to the string.  If it
-is no match is possible even with further text, this field will be set 
+is no match is possible even with further text, this field will be set
 to \-1.
 .SH "SEE ALSO"
 re_syntax(n)
index 557391d..b2270a2 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -67,7 +67,7 @@ a superset of the functions provided by the other routines,
 any new code should only make use of the more powerful routines.
 The older, weaker routines \fBTcl_SaveResult\fR, \fBTcl_RestoreResult\fR,
 and \fBTcl_DiscardResult\fR continue to exist only for the sake
-of existing programs that may already be using them.  
+of existing programs that may already be using them.
 .PP
 \fBTcl_SaveInterpState\fR takes a snapshot of those portions of
 interpreter state that make up the full result of script evaluation.
@@ -115,6 +115,6 @@ uninitialized state and cannot be used until another call to
 Once \fBTcl_SaveResult\fR is called to save the interpreter
 result, either \fBTcl_RestoreResult\fR or
 \fBTcl_DiscardResult\fR must be called to properly clean up the
-memory associated with the saved state.  
+memory associated with the saved state.
 .SH KEYWORDS
 result, state, interp
index 1f86340..e5b81d7 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_SetResult 3 8.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -164,7 +164,7 @@ The source interpreter will have its result reset by this operation.
 .SH "DEPRECATED INTERFACES"
 .SS "OLD STRING PROCEDURES"
 .PP
-Use of the following procedures (is deprecated
+Use of the following procedures is deprecated
 since they manipulate the Tcl result as a string.
 Procedures such as \fBTcl_SetObjResult\fR
 that manipulate the result as a value
@@ -212,7 +212,7 @@ As a migration aid, access can be restored with the compiler directive
 but this is meant only to offer life support to otherwise dead code.
 .SH "THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT"
 .PP
-\fBTcl_SetResult\fR's \fIfreeProc\fR argument specifies how 
+\fBTcl_SetResult\fR's \fIfreeProc\fR argument specifies how
 the Tcl system is to manage the storage for the \fIresult\fR argument.
 If \fBTcl_SetResult\fR or \fBTcl_SetObjResult\fR are called
 at a time when \fIinterp\fR holds a string result,
index 1bef20b..4aa671a 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_SetVar 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -86,7 +86,7 @@ These procedures are used to create, modify, read, and delete
 Tcl variables from C code.
 .PP
 \fBTcl_SetVar2Ex\fR, \fBTcl_SetVar\fR, \fBTcl_SetVar2\fR, and
-\fBTcl_ObjSetVar2\fR 
+\fBTcl_ObjSetVar2\fR
 will create a new variable or modify an existing one.
 These procedures set the given variable to the value
 given by \fInewValuePtr\fR or \fInewValue\fR and return a
index c7fa9f6..fc3b477 100644 (file)
--- a/doc/Tcl.n
+++ b/doc/Tcl.n
@@ -191,30 +191,30 @@ in braces or quotes.
 Backslash
 .PQ \e "" .
 .TP 7
-\e\fIooo\fR 
+\e\fIooo\fR
 .
-The digits \fIooo\fR (one, two, or three of them) give a eight-bit octal 
+The digits \fIooo\fR (one, two, or three of them) give a eight-bit octal
 value for the Unicode character that will be inserted, in the range
 \fI000\fR\(en\fI377\fR (i.e., the range U+000000\(enU+0000FF).
 The parser will stop just before this range overflows, or when
 the maximum of three digits is reached.  The upper bits of the Unicode
 character will be 0.
 .TP 7
-\e\fBx\fIhh\fR 
+\e\fBx\fIhh\fR
 .
 The hexadecimal digits \fIhh\fR (one or two of them) give an eight-bit
 hexadecimal value for the Unicode character that will be inserted.  The upper
 bits of the Unicode character will be 0 (i.e., the character will be in the
 range U+000000\(enU+0000FF).
 .TP 7
-\e\fBu\fIhhhh\fR 
+\e\fBu\fIhhhh\fR
 .
 The hexadecimal digits \fIhhhh\fR (one, two, three, or four of them) give a
 sixteen-bit hexadecimal value for the Unicode character that will be
 inserted.  The upper bits of the Unicode character will be 0 (i.e., the
 character will be in the range U+000000\(enU+00FFFF).
 .TP 7
-\e\fBU\fIhhhhhhhh\fR 
+\e\fBU\fIhhhhhhhh\fR
 .
 The hexadecimal digits \fIhhhhhhhh\fR (one up to eight of them) give a
 twenty-one-bit hexadecimal value for the Unicode character that will be
index 5fd5002..3ec33d1 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_Main 3 8.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -52,7 +52,7 @@ is a program
 like tclsh or wish that supports both interactive interpretation
 of Tcl and evaluation of a script contained in a file given as
 a command line argument.  \fBTcl_Main\fR is offered as a convenience
-to developers of shell applications, so they do not have to 
+to developers of shell applications, so they do not have to
 reproduce all of the code for proper initialization of the Tcl
 library and interactive shell operation.  Other styles of embedding
 Tcl in an application are not supported by \fBTcl_Main\fR.  Those
@@ -106,7 +106,7 @@ will not evaluate any startup script.
 and encoding set by the most recent \fBTcl_SetStartupScript\fR
 call in the same thread.  The stored file name is returned,
 and the stored encoding name is written to space pointed to
-by \fIencodingPtr\fR, when that is not NULL.  
+by \fIencodingPtr\fR, when that is not NULL.
 .PP
 The file name and encoding values managed by the routines
 \fBTcl_SetStartupScript\fR and \fBTcl_GetStartupScript\fR
@@ -136,7 +136,7 @@ commands, \fBTcl_Main\fR calls the procedure given by the
 .QW hook
 for the application to perform its own initialization of the interpreter
 created by \fBTcl_Main\fR, such as defining application-specific
-commands.  The application initialization routine might also 
+commands.  The application initialization routine might also
 call \fBTcl_SetStartupScript\fR to (re-)set the file and encoding
 to be used as a startup script.  The procedure must have an interface
 that matches the type \fBTcl_AppInitProc\fR:
index fccc0c6..99914a6 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_TraceCommand 3 7.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
index 97d035b..19cb467 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_TraceVar 3 7.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -203,7 +203,7 @@ The procedures \fBTcl_TraceVar2\fR, \fBTcl_UntraceVar2\fR, and
 except that the name of the variable consists of two parts.
 \fIName1\fR gives the name of a scalar variable or array,
 and \fIname2\fR gives the name of an element within an array.
-When \fIname2\fR is NULL, 
+When \fIname2\fR is NULL,
 \fIname1\fR may contain both an array and an element name:
 if the name contains an open parenthesis and ends with a
 close parenthesis, then the value between the parentheses is
@@ -214,7 +214,7 @@ If \fIname2\fR is NULL and \fIname1\fR does not refer
 to an array element it means that either the variable is
 a scalar or the trace is to be set on the entire array rather
 than an individual element (see WHOLE-ARRAY TRACES below for
-more information). 
+more information).
 .SH "ACCESSING VARIABLES DURING TRACES"
 .PP
 During read, write, and array traces, the
index 0f223e4..38831d3 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_TranslateFileName 3 8.1 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -34,7 +34,7 @@ anything stored here.
 This utility procedure translates a file name to a platform-specific form
 which, after being converted to the appropriate encoding, is suitable for
 passing to the local operating system.  In particular, it converts
-network names into native form and does tilde substitution.  
+network names into native form and does tilde substitution.
 .PP
 However, with the advent of the newer \fBTcl_FSGetNormalizedPath\fR and
 \fBTcl_FSGetNativePath\fR, there is no longer any need to use this
index ea6fc5b..2336c34 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_UniCharIsAlpha 3 "8.1" Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
index 8e7ba08..9e17ed5 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_UpVar 3 7.4 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -40,7 +40,7 @@ an upvar-ed variable.
 One of \fBTCL_GLOBAL_ONLY\fR, \fBTCL_NAMESPACE_ONLY\fR or 0;  if non-zero,
 then \fIdestName\fR is a global or namespace variable;  otherwise it is
 local to the current procedure (or current namespace if no procedure is
-active). 
+active).
 .AP "const char" *name1 in
 First part of source variable's name (scalar name, or name of array
 without array index).
index 33807d5..93e2ebb 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH Tcl_WrongNumArgs 3 8.0 Tcl "Tcl Library Procedures"
 .so man.macros
 .BS
@@ -55,7 +55,7 @@ wrong # args: should be "foo bar fileName count"
 .PP
 \fIObjc\fR is usually 1, but may be 2 or more for commands like
 \fBstring\fR and the Tk widget commands, which use the first argument
-as a subcommand.  
+as a subcommand.
 .PP
 Some of the values in the \fIobjv\fR array may be abbreviations for
 a subcommand.  The command
index e61bb88..3d0d2c4 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH after n 7.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -47,7 +47,7 @@ The delayed command is formed by concatenating all the \fIscript\fR
 arguments in the same fashion as the \fBconcat\fR command.
 The command will be executed at global level (outside the context
 of any Tcl procedure).
-If an error occurs while executing the delayed command then 
+If an error occurs while executing the delayed command then
 the background error will be reported by the command
 registered with \fBinterp bgerror\fR.
 The \fBafter\fR command returns an identifier that can be used
index 4b3cfd0..e3bf224 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH append n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index 4b730ff..aeb2227 100644 (file)
@@ -14,11 +14,11 @@ apply \- Apply an anonymous function
 .SH DESCRIPTION
 .PP
 The command \fBapply\fR applies the function \fIfunc\fR to the arguments
-\fIarg1 arg2 ...\fR and returns the result. 
+\fIarg1 arg2 ...\fR and returns the result.
 .PP
 The function \fIfunc\fR is a two element list \fI{args body}\fR or a three
 element list \fI{args body namespace}\fR (as if the
-\fBlist\fR command had been used). 
+\fBlist\fR command had been used).
 The first element \fIargs\fR specifies the formal arguments to
 \fIfunc\fR. The specification of the formal arguments \fIargs\fR
 is shared with the \fBproc\fR command, and is described in detail in the
@@ -96,7 +96,7 @@ set vbl abc
 .SH "SEE ALSO"
 proc(n), uplevel(n)
 .SH KEYWORDS
-anonymous function, argument, lambda, procedure, 
+anonymous function, argument, lambda, procedure,
 '\" Local Variables:
 '\" mode: nroff
 '\" End:
index e253a37..25ad0c6 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH array n 8.3 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index ea8fe2a..3644b3d 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH bgerror n 7.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index 014704d..5f25d65 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH binary n 8.0 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -300,7 +300,7 @@ example,
 .CS
 \fBbinary format\fR s3 {3 -3 258 1}
 .CE
-will return a string equivalent to 
+will return a string equivalent to
 \fB\ex03\ex00\exfd\exff\ex02\ex01\fR.
 .RE
 .IP \fBS\fR 5
@@ -311,7 +311,7 @@ example,
 .CS
 \fBbinary format\fR S3 {3 -3 258 1}
 .CE
-will return a string equivalent to 
+will return a string equivalent to
 \fB\ex00\ex03\exff\exfd\ex01\ex02\fR.
 .RE
 .IP \fBt\fR 5
@@ -330,7 +330,7 @@ example,
 .CS
 \fBbinary format\fR i3 {3 -3 65536 1}
 .CE
-will return a string equivalent to 
+will return a string equivalent to
 \fB\ex03\ex00\ex00\ex00\exfd\exff\exff\exff\ex00\ex00\ex01\ex00\fR
 .RE
 .IP \fBI\fR 5
@@ -341,7 +341,7 @@ For example,
 .CS
 \fBbinary format\fR I3 {3 -3 65536 1}
 .CE
-will return a string equivalent to 
+will return a string equivalent to
 \fB\ex00\ex00\ex00\ex03\exff\exff\exff\exfd\ex00\ex01\ex00\ex00\fR
 .RE
 .IP \fBn\fR 5
@@ -397,7 +397,7 @@ on a Windows system running on an Intel Pentium processor,
 .CS
 \fBbinary format\fR f2 {1.6 3.4}
 .CE
-will return a string equivalent to 
+will return a string equivalent to
 \fB\excd\excc\excc\ex3f\ex9a\ex99\ex59\ex40\fR.
 .RE
 .IP \fBr\fR 5
@@ -418,7 +418,7 @@ Windows system running on an Intel Pentium processor,
 .CS
 \fBbinary format\fR d1 {1.6}
 .CE
-will return a string equivalent to 
+will return a string equivalent to
 \fB\ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f\fR.
 .RE
 .IP \fBq\fR 5
@@ -684,7 +684,7 @@ order.  For example,
 \fBbinary scan\fR \ex00\ex05\ex00\ex07\exff\exf0 S2S* var1 var2
 .CE
 will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
-stored in \fIvar2\fR. 
+stored in \fIvar2\fR.
 .RE
 .IP \fBt\fR 5
 The data is interpreted as \fIcount\fR 16-bit signed integers
index 94fa5dd..d43a7ec 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH catch n "8.5" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -43,7 +43,7 @@ value stored in \fIresultVarName\fR is the value returned from \fIscript\fR.
 .PP
 If the \fIoptionsVarName\fR argument is given, then the variable it
 names is set to a dictionary of return options returned by evaluation
-of \fIscript\fR.  Tcl specifies two entries that are always 
+of \fIscript\fR.  Tcl specifies two entries that are always
 defined in the dictionary: \fB\-code\fR and \fB\-level\fR.  When
 the return code from evaluation of \fIscript\fR is not \fBTCL_RETURN\fR,
 the value of the \fB\-level\fR entry will be 0, and the value
@@ -114,7 +114,7 @@ if { [\fBcatch\fR {open $someFile w} fid] } {
 .PP
 There are more complex examples of \fBcatch\fR usage in the
 documentation for the \fBreturn\fR command.
-.SH "SEE ALSO" 
+.SH "SEE ALSO"
 break(n), continue(n), dict(n), error(n), errorCode(n), errorInfo(n), info(n),
 return(n)
 .SH KEYWORDS
index 12b2c81..81aa9f4 100644 (file)
@@ -1,4 +1,4 @@
-'\" 
+'\"
 '\" Copyright (c) 2005-2006 Donal K. Fellows
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
@@ -200,7 +200,7 @@ generate an error.
 .TP
 \fB\-translation\fR \fImode\fR
 .TP
-\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR 
+\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR
 .
 In Tcl scripts the end of a line is always represented using a single
 newline character (\en).  However, in actual files and devices the end
@@ -240,7 +240,7 @@ all platforms Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses
 \fBcrlf\fR.  The default setting for \fB\-translation\fR is \fBauto\fR
 for both input and output.
 .TP
-\fBbinary\fR 
+\fBbinary\fR
 .
 No end-of-line translations are performed.  This is nearly identical
 to \fBlf\fR mode, except that in addition \fBbinary\fR mode also sets
@@ -287,12 +287,14 @@ slow destinations like network sockets.
 .RS
 .PP
 The \fBchan copy\fR command transfers data from \fIinputChan\fR until
-end of file or \fIsize\fR bytes have been transferred. If no
-\fB\-size\fR argument is given, then the copy goes until end of file.
-All the data read from \fIinputChan\fR is copied to \fIoutputChan\fR.
-Without the \fB\-command\fR option, \fBchan copy\fR blocks until the
-copy is complete and returns the number of bytes written to
-\fIoutputChan\fR.
+end of file or \fIsize\fR bytes or characters have been transferred;
+\fIsize\fR is in bytes if the two channels are using the same encoding,
+and is in characters otherwise.  If no \fB\-size\fR argument is given,
+then the copy goes until end of file. All the data read from
+\fIinputChan\fR is copied to \fIoutputChan\fR.  Without the
+\fB\-command\fR option, \fBchan copy\fR blocks until the copy is
+complete and returns the number of bytes or characters (using the same
+rules as for the \fB\-size\fR option) written to \fIoutputChan\fR.
 .PP
 The \fB\-command\fR argument makes \fBchan copy\fR work in the
 background.  In this case it returns immediately and the
@@ -530,8 +532,8 @@ only those channel names that match it (according to the rules of
 .
 Depending on whether \fImode\fR is \fBinput\fR or \fBoutput\fR,
 returns the number of
-bytes of input or output (respectively) currently buffered 
-internally for \fIchannelId\fR (especially useful in a readable event 
+bytes of input or output (respectively) currently buffered
+internally for \fIchannelId\fR (especially useful in a readable event
 callback to impose application-specific limits on input line lengths to avoid
 a potential denial-of-service attack where a hostile user crafts
 an extremely long line that exceeds the available memory to buffer it).
@@ -546,7 +548,19 @@ separately \fBstderr\fR and \fBstdout\fR from a subprocess. To do
 this, spawn with "2>@" or
 ">@" redirection operators onto the write side of a pipe, and then
 immediately close it in the parent. This is necessary to get an EOF on
-the read side once the child has exited or otherwise closed its output. 
+the read side once the child has exited or otherwise closed its output.
+.RS
+.PP
+Note that the pipe buffering semantics can vary at the operating system level
+substantially; it is not safe to assume that a write performed on the output
+side of the pipe will appear instantly to the input side. This is a
+fundamental difference and Tcl cannot conceal it. The overall stream semantics
+\fIare\fR compatible, so blocking reads and writes will not see most of the
+differences, but the details of what exactly gets written when are not. This
+is most likely to show up when using pipelines for testing; care should be
+taken to ensure that deadlocks do not occur and that potential short reads are
+allowed for.
+.RE
 .VE 8.6
 .TP
 \fBchan pop \fIchannelId\fR
index 37d491b..ac3d8ed 100644 (file)
--- a/doc/dde.n
+++ b/doc/dde.n
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH dde n 1.4 dde "Tcl Bundled Packages"
 .so man.macros
 .BS
@@ -85,7 +85,7 @@ the command returns immediately with no error.
 .VS 8.6
 Without the \fB\-binary\fR option all data will be sent in unicode. For
 dde clients which don't implement the CF_UNICODE clipboard format, this
-will automatically be translated to the system encoding. You can use 
+will automatically be translated to the system encoding. You can use
 the \fB\-binary\fR option in combination with the result of
 \fBencoding convertto\fR to send data in any other encoding.
 .VE 8.6
@@ -102,7 +102,7 @@ application.
 .VS 8.6
 Without the \fB\-binary\fR option all data will be sent in unicode. For
 dde clients which don't implement the CF_UNICODE clipboard format, this
-will automatically be translated to the system encoding. You can use 
+will automatically be translated to the system encoding. You can use
 the \fB\-binary\fR option in combination with the result of
 \fBencoding convertto\fR to send data in any other encoding.
 .VE 8.6
index 5782199..50ad083 100644 (file)
@@ -1,9 +1,9 @@
 '\"
 '\" Copyright (c) 1998 by Scriptics Corporation.
-'\" 
+'\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH encoding n "8.1" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -67,7 +67,7 @@ searchable directory, that element is ignored.
 \fBencoding names\fR
 .
 Returns a list containing the names of all of the encodings that are
-currently available. 
+currently available.
 The encodings
 .QW utf-8
 and
index a95c691..c05f8b9 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH error n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -28,7 +28,7 @@ the Tcl interpreter adds information to the \fB\-errorinfo\fR
 return option.  If the \fIinfo\fR argument is present, it is
 used to initialize the \fB\-errorinfo\fR return options and
 the first increment of unwind information
-will not be added by the Tcl interpreter.  
+will not be added by the Tcl interpreter.
 In other
 words, the command containing the \fBerror\fR command will not appear
 in the stack trace; in its place will be \fIinfo\fR.
index 5b27e40..70ace32 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH exec n 8.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -220,7 +220,7 @@ discarded.
 The Tk console text widget does not provide real standard IO capabilities.
 Under Tk, when redirecting from standard input, all applications will see an
 immediate end-of-file; information redirected to standard output or standard
-error will be discarded.  
+error will be discarded.
 .PP
 Either forward or backward slashes are accepted as path separators for
 arguments to Tcl commands.  When executing an application, the path name
@@ -231,7 +231,7 @@ backslashes only in paths.  Any arguments to an application that specify a
 path name with forward slashes will not automatically be converted to use
 the backslash character.  If an argument contains forward slashes as the
 path separator, it may or may not be recognized as a path name, depending on
-the program.  
+the program.
 .PP
 Additionally, when calling a 16-bit DOS or Windows 3.X application, all path
 names must use the short, cryptic, path format (e.g., using
@@ -271,8 +271,9 @@ limitation as \fBexec\fR wants to communicate over pipes.  The Expect
 extension addresses this issue when communicating with a TUI application.
 .PP
 When attempting to execute an application, \fBexec\fR first searches for
-the name as it was specified.  Then, in order, \fB.com\fR, \fB.exe\fR, and
-\fB.bat\fR are appended to the end of the specified name and it searches
+the name as it was specified.  Then, in order,
+\fB.com\fR, \fB.exe\fR, \fB.bat\fR and \fB.cmd\fR
+are appended to the end of the specified name and it searches
 for the longer name.  If a directory name was not specified as part of the
 application name, the following directories are automatically searched in
 order when attempting to locate the application:
index a595207..b76b6a2 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH expr n 8.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -398,7 +398,7 @@ Most expressions do not require a second round of substitutions.
 Either they are enclosed in braces or, if not,
 their variable and command substitutions yield numbers or strings
 that do not themselves require substitutions.
-However, because a few unbraced expressions 
+However, because a few unbraced expressions
 need two rounds of substitutions,
 the bytecode compiler must emit
 additional instructions to handle this situation.
index ca23314..8da76c6 100644 (file)
@@ -1,4 +1,4 @@
-'\" 
+'\"
 '\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
@@ -125,7 +125,7 @@ generate an error.
 .TP
 \fB\-translation\fR \fImode\fR
 .TP
-\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR 
+\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR
 .
 In Tcl scripts the end of a line is always represented using a single
 newline character (\en).  However, in actual files and devices the end of
@@ -163,7 +163,7 @@ Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses \fBlf\fR, and
 for the various flavors of Windows it chooses \fBcrlf\fR.  The default
 setting for \fB\-translation\fR is \fBauto\fR for both input and output.
 .TP
-\fBbinary\fR 
+\fBbinary\fR
 .
 No end-of-line translations are performed.  This is nearly identical to
 \fBlf\fR mode, except that in addition \fBbinary\fR mode also sets the
index 071896c..d39c803 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH fcopy n 8.0 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -23,20 +23,23 @@ avoid extra copies and to avoid buffering too much data in
 main memory when copying large files to slow destinations like
 network sockets.
 .PP
-The \fBfcopy\fR 
+The \fBfcopy\fR
 command transfers data from \fIinchan\fR until end of file
-or \fIsize\fR bytes have been 
-transferred. If no \fB\-size\fR argument is given,
+or \fIsize\fR bytes or characters have been
+transferred; \fIsize\fR is in bytes if the two channels are using the
+same encoding, and is in characters otherwise.
+If no \fB\-size\fR argument is given,
 then the copy goes until end of file.
 All the data read from \fIinchan\fR is copied to \fIoutchan\fR.
 Without the \fB\-command\fR option, \fBfcopy\fR blocks until the copy is complete
-and returns the number of bytes written to \fIoutchan\fR.
+and returns the number of bytes or characters (using the same rules as
+for the \fB\-size\fR option) written to \fIoutchan\fR.
 .PP
 The \fB\-command\fR argument makes \fBfcopy\fR work in the background.
 In this case it returns immediately and the \fIcallback\fR is invoked
 later when the copy completes.
 The \fIcallback\fR is called with
-one or two additional 
+one or two additional
 arguments that indicates how many bytes were written to \fIoutchan\fR.
 If an error occurred during the background copy, the second argument is the
 error string associated with the error.
@@ -109,7 +112,7 @@ fconfigure $out -translation binary
 This second example shows how the callback gets
 passed the number of bytes transferred.
 It also uses vwait to put the application into the event loop.
-Of course, this simplified example could be done without the command 
+Of course, this simplified example could be done without the command
 callback.
 .PP
 .CS
@@ -174,3 +177,6 @@ vwait done
 eof(n), fblocked(n), fconfigure(n), file(n)
 .SH KEYWORDS
 blocking, channel, end of line, end of file, nonblocking, read, translation
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
index 9f89f6d..2f8b70c 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH file n 8.3 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -141,7 +141,7 @@ returned.  For example,
 \fBfile dirname\fR c:/
 .CE
 .PP
-returns \fBc:/\fR. 
+returns \fBc:/\fR.
 .PP
 Note that tilde substitution will only be
 performed if it is necessary to complete the command. For example,
@@ -162,7 +162,9 @@ returns \fB/home\fR (or something similar).
 \fBfile executable \fIname\fR
 .
 Returns \fB1\fR if file \fIname\fR is executable by the current user,
-\fB0\fR otherwise.  
+\fB0\fR otherwise. On Windows, which does not have an executable attribute,
+the command treats all directories and any files with extensions
+\fBexe\fR, \fBcom\fR, \fBcmd\fR or \fBbat\fR as executable.
 .TP
 \fBfile exists \fIname\fR
 .
@@ -300,7 +302,7 @@ operate on the actual symbolic link itself (for example \fBfile delete\fR,
 \fBfile rename\fR, \fBfile copy\fR are defined to operate on symbolic
 links, not on the things that they point to).
 .TP
-\fBfile owned \fIname\fR 
+\fBfile owned \fIname\fR
 .
 Returns \fB1\fR if file \fIname\fR is owned by the current user, \fB0\fR
 otherwise.
@@ -318,7 +320,7 @@ type is \fBvolumerelative\fR.
 \fBfile readable \fIname\fR
 .
 Returns \fB1\fR if file \fIname\fR is readable by the current user,
-\fB0\fR otherwise. 
+\fB0\fR otherwise.
 .TP
 \fBfile readlink \fIname\fR
 .
@@ -356,7 +358,7 @@ component of \fIname\fR does not contain a dot, then returns \fIname\fR.
 .TP
 \fBfile separator\fR ?\fIname\fR?
 .
-If no argument is given, returns the character which is used to separate 
+If no argument is given, returns the character which is used to separate
 path segments for native files on this platform.  If a path is given,
 the filesystem responsible for that path is asked to return its
 separator character.  If no file system accepts \fIname\fR, an error
@@ -427,7 +429,7 @@ If the file does not belong to any filesystem, an error is generated.
 .
 Returns all of the characters in the last filesystem component of
 \fIname\fR.  Any trailing directory separator in \fIname\fR is ignored.
-If \fIname\fR contains no separators then returns \fIname\fR.  So, 
+If \fIname\fR contains no separators then returns \fIname\fR.  So,
 \fBfile tail a/b\fR, \fBfile tail a/b/\fR and \fBfile tail b\fR all
 return \fBb\fR.
 .TP
@@ -457,7 +459,7 @@ Returns a string giving the type of file \fIname\fR, which will be one of
 \fBfifo\fR, \fBlink\fR, or \fBsocket\fR.
 .TP
 \fBfile volumes\fR
-. 
+.
 Returns the absolute paths to the volumes mounted on the system, as a
 proper Tcl list.  Without any virtual filesystems mounted as root
 volumes, on UNIX, the command will always return
@@ -478,14 +480,13 @@ Returns \fB1\fR if file \fIname\fR is writable by the current user,
 \fBUnix\fR\0\0\0\0\0\0\0
 .
 These commands always operate using the real user and group identifiers,
-not the effective ones. 
+not the effective ones.
 .TP
 \fBWindows\fR\0\0\0\0
 .
-The \fBfile owned\fR subcommand currently always reports that the current user
-is the owner of the file, without regard for what the operating system
-believes to be true, making an ownership test useless. This issue (#3613671)
-may be fixed in a future release of Tcl.
+The \fBfile owned\fR subcommand uses the user identifier (SID) of
+the process token, not the thread token which may be impersonating
+some other user.
 .SH EXAMPLES
 .PP
 This procedure shows how to search for C files in a given directory
index 8f6b880..2751040 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH fileevent n 7.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -112,7 +112,7 @@ buggy handlers.
 In this setup \fBGetData\fR will be called with the channel as an
 argument whenever $chan becomes readable. The \fBread\fR call will
 read whatever binary data is currently available without blocking.
-Here the channel has the fileevent removed when an end of file 
+Here the channel has the fileevent removed when an end of file
 occurs to avoid being continually called (see above). Alternatively
 the channel may be closed on this condition.
 .PP
index 8b8b00b..87ba467 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH filename n 7.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -29,7 +29,7 @@ File names are grouped into three general types based on the starting point
 for the path used to specify the file: absolute, relative, and
 volume-relative.  Absolute names are completely qualified, giving a path to
 the file relative to a particular volume and the root directory on that
-volume.  Relative names are unqualified, giving a path to the file relative 
+volume.  Relative names are unqualified, giving a path to the file relative
 to the current working directory.  Volume-relative names are partially
 qualified, either giving the path relative to the root directory on the
 current volume, or relative to the current directory of the specified
@@ -75,7 +75,7 @@ current directory.
 .TP 15
 \fB\&../foo\fR
 Relative path to the file \fBfoo\fR in the directory above the current
-directory. 
+directory.
 .RE
 .TP
 \fBWindows\fR
@@ -84,7 +84,7 @@ style names.  Both \fB/\fR and \fB\e\fR may be used as directory separators
 in either type of name.  Drive-relative names consist of an optional drive
 specifier followed by an absolute or relative path.  UNC paths follow the
 general form \fB\e\eservername\esharename\epath\efile\fR, but must at
-the very least contain the server and share components, i.e. 
+the very least contain the server and share components, i.e.
 \fB\e\eservername\esharename\fR.  In both forms,
 the file names \fB.\fR and \fB..\fR are special and refer to the current
 directory and the parent of the current directory respectively.  The
@@ -154,7 +154,7 @@ native path names).  Also Windows 3.1 only supports file
 names with a root of no more than 8 characters and an extension of no
 more than 3 characters.
 .PP
-On Windows platforms there are file and path length restrictions. 
+On Windows platforms there are file and path length restrictions.
 Complete paths or filenames longer than about 260 characters will lead
 to errors in most file operations.
 .PP
index 076a820..ba044f2 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH format n 8.1 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -25,14 +25,14 @@ arguments, if any, provide values to be substituted into the result.
 The return value from \fBformat\fR is the formatted string.
 .SH "DETAILS ON FORMATTING"
 .PP
-The command operates by scanning \fIformatString\fR from left to right. 
+The command operates by scanning \fIformatString\fR from left to right.
 Each character from the format string is appended to the result
 string unless it is a percent sign.
 If the character is a \fB%\fR then it is not copied to the result string.
 Instead, the characters following the \fB%\fR character are treated as
 a conversion specifier.
 The conversion specifier controls the conversion of the next successive
-\fIarg\fR to a particular format and the result is appended to 
+\fIarg\fR to a particular format and the result is appended to
 the result string in place of the conversion specifier.
 If there are multiple conversion specifiers in the format string,
 then each one controls the conversion of one additional \fIarg\fR.
@@ -66,12 +66,12 @@ The second portion of a conversion specifier may contain any of the
 following flag characters, in any order:
 .TP 10
 \fB\-\fR
-Specifies that the converted argument should be left-justified 
-in its field (numbers are normally right-justified with leading 
+Specifies that the converted argument should be left-justified
+in its field (numbers are normally right-justified with leading
 spaces if needed).
 .TP 10
 \fB+\fR
-Specifies that a number should always be printed with a sign, 
+Specifies that a number should always be printed with a sign,
 even if positive.
 .TP 10
 \fIspace\fR
@@ -79,7 +79,7 @@ Specifies that a space should be added to the beginning of the
 number if the first character is not a sign.
 .TP 10
 \fB0\fR
-Specifies that the number should be padded on the left with 
+Specifies that the number should be padded on the left with
 zeroes instead of spaces.
 .TP 10
 \fB#\fR
@@ -90,9 +90,9 @@ will be added to the beginning of the result unless it is zero.
 For \fBb\fR conversions, \fB0b\fR
 will be added to the beginning of the result unless it is zero.
 For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
-\fBg\fR, and \fBG\fR) it guarantees that the result always 
+\fBg\fR, and \fBG\fR) it guarantees that the result always
 has a decimal point.
-For \fBg\fR and \fBG\fR conversions it specifies that 
+For \fBg\fR and \fBG\fR conversions it specifies that
 trailing zeroes should not be removed.
 .SS "OPTIONAL FIELD WIDTH"
 .PP
@@ -103,7 +103,7 @@ If the converted argument contains fewer characters than the
 minimum field width then it will be padded so that it is as wide
 as the minimum field width.
 Padding normally occurs by adding extra spaces on the left of the
-converted argument, but the \fB0\fR and \fB\-\fR flags 
+converted argument, but the \fB0\fR and \fB\-\fR flags
 may be used to specify padding with zeroes on the left or with
 spaces on the right, respectively.
 If the minimum field width is specified as \fB*\fR rather than
@@ -122,7 +122,7 @@ point (however, trailing zeroes after the decimal point will still
 be omitted unless the \fB#\fR flag has been specified).
 For integer conversions, it specifies a minimum number of digits
 to print (leading zeroes will be added if necessary).
-For \fBs\fR conversions it specifies the maximum number of characters to be 
+For \fBs\fR conversions it specifies the maximum number of characters to be
 printed; if the string is longer than this then the trailing characters will be dropped.
 If the precision is specified with \fB*\fR rather than a number
 then the next argument to the \fBformat\fR command determines the precision;
@@ -135,7 +135,7 @@ If it is \fBll\fR it specifies that an integer value is taken
 without truncation for conversion to a formatted substring.
 If it is \fBh\fR it specifies that an integer value is
 truncated to a 16-bit range before converting.  This option is rarely useful.
-If it is \fBl\fR it specifies that the integer value is 
+If it is \fBl\fR it specifies that the integer value is
 truncated to the same range as that produced by the \fBwide()\fR
 function of the \fBexpr\fR command (at least a 64-bit range).
 If neither \fBh\fR nor \fBl\fR are present, the integer value is
@@ -178,22 +178,22 @@ Convert integer to the Unicode character it represents.
 No conversion; just insert string.
 .TP 10
 \fBf\fR
-Convert number to signed decimal string of 
-the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by 
+Convert number to signed decimal string of
+the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by
 the precision (default: 6).
 If the precision is 0 then no decimal point is output.
 .TP 10
 \fBe\fR or \fBE\fR
-Convert number to scientific notation in the 
-form \fIx.yyy\fBe\(+-\fIzz\fR, where the number of \fIy\fR's is determined 
+Convert number to scientific notation in the
+form \fIx.yyy\fBe\(+-\fIzz\fR, where the number of \fIy\fR's is determined
 by the precision (default: 6).
 If the precision is 0 then no decimal point is output.
-If the \fBE\fR form is used then \fBE\fR is 
+If the \fBE\fR form is used then \fBE\fR is
 printed instead of \fBe\fR.
 .TP 10
 \fBg\fR or \fBG\fR
-If the exponent is less than \-4 or greater than or equal to the 
-precision, then convert number as for \fB%e\fR or 
+If the exponent is less than \-4 or greater than or equal to the
+precision, then convert number as for \fB%e\fR or
 \fB%E\fR.
 Otherwise convert as for \fB%f\fR.
 Trailing zeroes and a trailing decimal point are omitted.
index aa8f2e4..9848817 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH global n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -24,7 +24,7 @@ in the list returned by \fBinfo locals\fR).
 .PP
 If \fIvarname\fR contains namespace qualifiers, the local variable's name is
 the unqualified name of the global variable, as determined by the
-\fBnamespace tail\fR command. 
+\fBnamespace tail\fR command.
 .PP
 \fIvarname\fR is always treated as the name of a variable, not an
 array element.  An error is returned if the name looks like an array element,
index cdf9c56..80ae044 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH "http" n 2.7 http "Tcl Bundled Packages"
 .so man.macros
 .BS
@@ -60,7 +60,7 @@ a custom \fBsocket\fR command, via \fB::http::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.  
+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
@@ -90,7 +90,7 @@ flags and values that define the configuration:
 \fB\-accept\fR \fImimetypes\fR
 .
 The Accept header of the request.  The default is */*, which means that
-all types of documents are accepted.  Otherwise you can supply a 
+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,
 .QW "image/gif, image/jpeg, text/*" .
@@ -132,7 +132,7 @@ The value of the User-Agent header in the HTTP request.  The default is
 .QW "\fBTcl http client package 2.7\fR" .
 .RE
 .TP
-\fB::http::geturl\fR \fIurl\fR ?\fIoptions\fR? 
+\fB::http::geturl\fR \fIurl\fR ?\fIoptions\fR?
 .
 The \fB::http::geturl\fR command is the main procedure in the package.
 The \fB\-query\fR option causes a POST operation and
@@ -275,7 +275,7 @@ do the formatting.
 \fB\-queryblocksize\fR \fIsize\fR
 .
 The block size used when posting query data to the URL.
-At most 
+At most
 \fIsize\fR
 bytes are written at once.  After each block, a call to the
 \fB\-queryprogress\fR
index b42904b..d5605bc 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH lindex n 8.4 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -48,7 +48,7 @@ substitution and command substitution do not occur.
 If \fIindex\fR is negative or greater than or equal to the number
 of elements in \fIvalue\fR, then an empty
 string is returned.
-The interpretation of each simple \fIindex\fR value is the same as 
+The interpretation of each simple \fIindex\fR value is the same as
 for the command \fBstring index\fR, supporting simple index
 arithmetic and indices relative to the end of the list.
 .PP
@@ -115,7 +115,7 @@ set idx 3
       \fI\(-> f\fR
 .CE
 .SH "SEE ALSO"
-list(n), lappend(n), linsert(n), llength(n), lsearch(n), 
+list(n), lappend(n), linsert(n), llength(n), lsearch(n),
 lset(n), lsort(n), lrange(n), lreplace(n),
 string(n)
 .SH KEYWORDS
index 51b64cf..91db726 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH linsert n 8.2 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -45,7 +45,7 @@ set newList [\fBlinsert\fR $midList end-1 lazy]
 set newerList [\fBlinsert\fR [\fBlinsert\fR $oldList end-1 quick] 1 lazy]
 .CE
 .SH "SEE ALSO"
-list(n), lappend(n), lindex(n), llength(n), lsearch(n), 
+list(n), lappend(n), lindex(n), llength(n), lsearch(n),
 lset(n), lsort(n), lrange(n), lreplace(n),
 string(n)
 .SH KEYWORDS
index d3f9610..79f93c0 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH llength n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -49,7 +49,7 @@ An empty list is not necessarily an empty string:
 1,0
 .CE
 .SH "SEE ALSO"
-list(n), lappend(n), lindex(n), linsert(n), lsearch(n), 
+list(n), lappend(n), lindex(n), linsert(n), lsearch(n),
 lset(n), lsort(n), lrange(n), lreplace(n)
 .SH KEYWORDS
 element, list, length
index 2038fc2..1a7858d 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH lmap n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -51,7 +51,7 @@ Zip lists together:
 .CS
 set list1 {a b c d}
 set list2 {1 2 3 4}
-set zipped [\fBlmap\fR a $list1 b $list2 {list $a $b}] 
+set zipped [\fBlmap\fR a $list1 b $list2 {list $a $b}]
 # The value of zipped is "{a 1} {b 2} {c 3} {d 4}"
 .CE
 .PP
index 4e26a0f..ffa6dba 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH lrange n 7.4 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -71,7 +71,7 @@ elements to
 {elements to}
 .CE
 .SH "SEE ALSO"
-list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n), 
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
 lset(n), lreplace(n), lsort(n),
 string(n)
 .SH KEYWORDS
index 44ebce4..c2644b8 100644 (file)
@@ -1,4 +1,4 @@
-'\" 
+'\"
 '\" Copyright (c) 1993 The Regents of the University of California.
 '\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
 '\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
@@ -6,7 +6,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH lsearch n 8.6 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -111,7 +111,7 @@ The list elements are to be compared as integers.
 \fB\-nocase\fR
 .
 Causes comparisons to be handled in a case-insensitive manner.  Has no
-effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or 
+effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or
 \fB\-real\fR options.
 .TP
 \fB\-real\fR
@@ -209,7 +209,7 @@ It is also possible to search inside elements:
       \fI\(-> {a abc} {b bcd}\fR
 .CE
 .SH "SEE ALSO"
-foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n), 
+foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n),
 lset(n), lsort(n), lrange(n), lreplace(n),
 string(n)
 .SH KEYWORDS
index 954bd30..e425274 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH lset n 8.4 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -16,7 +16,7 @@ lset \- Change an element in a list
 .SH DESCRIPTION
 .PP
 The \fBlset\fR command accepts a parameter, \fIvarName\fR, which
-it interprets as the name of a variable containing a Tcl list. 
+it interprets as the name of a variable containing a Tcl list.
 It also accepts zero or more \fIindices\fR into
 the list.  The indices may be presented either consecutively on the
 command line, or grouped in a
@@ -40,7 +40,7 @@ In this case, \fInewValue\fR replaces the old value of the variable
 .PP
 When presented with a single index, the \fBlset\fR command
 treats the content of the \fIvarName\fR variable as a Tcl list.
-It addresses the \fIindex\fR'th element in it 
+It addresses the \fIindex\fR'th element in it
 (0 refers to the first element of the list).
 When interpreting the list, \fBlset\fR observes the same rules
 concerning braces and quotes and backslashes as the Tcl command
@@ -136,7 +136,7 @@ The indicated return value also becomes the new value of \fIx\fR.
       \fI\(-> {{a b} {c d}} {{e f} {j h}}\fR
 .CE
 .SH "SEE ALSO"
-list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n), 
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
 lsort(n), lrange(n), lreplace(n),
 string(n)
 .SH KEYWORDS
index 48c62f0..b0f7973 100644 (file)
@@ -6,7 +6,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH lsort n 8.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -153,14 +153,14 @@ returns
 \fB\-nocase\fR
 .
 Causes comparisons to be handled in a case-insensitive manner.  Has no
-effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or 
+effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or
 \fB\-real\fR options.
 .TP
 \fB\-unique\fR
 .
 If this option is specified, then only the last set of duplicate
 elements found in the list will be retained.  Note that duplicates are
-determined relative to the comparison used in the sort.  Thus if 
+determined relative to the comparison used in the sort.  Thus if
 \fB\-index 0\fR is used, \fB{1 a}\fR and \fB{1 b}\fR would be
 considered duplicates and only the second element, \fB{1 b}\fR, would
 be retained.
@@ -265,7 +265,7 @@ More complex sorting using a comparison function:
 {1 dingo} {2 banana} {0x2 carrot} {3 apple}
 .CE
 .SH "SEE ALSO"
-list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n), 
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
 lset(n), lrange(n), lreplace(n)
 .SH KEYWORDS
 element, list, order, sort
index 84853d8..7233d46 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH mathfunc n 8.5 Tcl "Tcl Mathematical Functions"
 .so man.macros
 .BS
@@ -142,7 +142,7 @@ than \fI0\fR, this is equivalent to
 \fBbool \fIarg\fR
 .
 Accepts any numeric value, or any string acceptable to
-\fBstring is boolean\fR, and returns the corresponding 
+\fBstring is boolean\fR, and returns the corresponding
 boolean value \fB0\fR or \fB1\fR.  Non-zero numbers are true.
 Other numbers are false.  Non-numeric strings produce boolean value in
 agreement with \fBstring is true\fR and \fBstring is false\fR.
@@ -243,7 +243,7 @@ is negative, \fIy\fR must be an integer value.
 .TP
 \fBrand\fR
 .
-Returns a pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).  
+Returns a pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).
 The generator algorithm is a simple linear congruential generator that
 is not cryptographically secure.  Each result from \fBrand\fR completely
 determines all future results from subsequent calls to \fBrand\fR, so
@@ -290,7 +290,7 @@ Returns the hyperbolic tangent of \fIarg\fR.
 .
 The argument may be any numeric value.  The integer part of \fIarg\fR
 is determined, and then the low order 64 bits of that integer value
-are returned as an integer value.  
+are returned as an integer value.
 .SH "SEE ALSO"
 expr(n), mathop(n), namespace(n)
 .SH "COPYRIGHT"
index 5a1524b..c8cdb21 100644 (file)
@@ -2,7 +2,7 @@
 '\" Copyright (c) 1992-1999 by Karl Lehenbauer and Mark Diekhans
 '\" Copyright (c) 2000 by Scriptics Corporation.
 '\" All rights reserved.
-'\" 
+'\"
 .TH memory n 8.1 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -33,9 +33,9 @@ command mode.
 .TP
 \fBmemory info\fR
 .
-Returns a report containing the total allocations and frees since 
+Returns a report containing the total allocations and frees since
 Tcl began, the current packets allocated (the current
-number of calls to \fBckalloc\fR not met by a corresponding call 
+number of calls to \fBckalloc\fR not met by a corresponding call
 to \fBckfree\fR), the current bytes allocated, and the maximum number
 of packets and bytes allocated.
 .TP
@@ -64,7 +64,7 @@ with it a string-valued tag.  In the lists of allocated memory generated
 by \fBmemory active\fR and \fBmemory onexit\fR, the tag for each packet
 is printed along with other information about the packet.  The
 \fBmemory tag\fR command sets the tag value for subsequent calls
-to \fBckalloc\fR to be \fIstring\fR.  
+to \fBckalloc\fR to be \fIstring\fR.
 .TP
 \fBmemory trace \fR[\fBon\fR|\fBoff\fR]
 .
@@ -91,7 +91,7 @@ being displayed for all allocations and frees.  Since there can be a lot
 of memory activity before a problem occurs, judicious use of this option
 can reduce the slowdown caused by tracing (and the amount of trace information
 produced), if you can identify a number of allocations that occur before
-the problem sets in.  The current number of memory allocations that have 
+the problem sets in.  The current number of memory allocations that have
 occurred since Tcl started is printed on a guard zone failure.
 .TP
 \fBmemory validate \fR[\fBon\fR|\fBoff\fR]
index 34e153d..2fc1eee 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH "msgcat" n 1.5 msgcat "Tcl Bundled Packages"
 .so man.macros
 .BS
@@ -259,7 +259,7 @@ language[_country][.codeset][@modifier]
 .CE
 .PP
 to extract its parts.  The initial locale is then set by calling
-\fB::msgcat::mclocale\fR with the argument 
+\fB::msgcat::mclocale\fR with the argument
 .PP
 .CS
 language[_country][_modifier]
index 3012460..1cccc0a 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH open n 8.3 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -68,7 +68,7 @@ Set the initial access position  to the end of the file.
 All of the legal \fIaccess\fR values above may have the character
 \fBb\fR added as the second or third character in the value to
 indicate that the opened channel should be configured as if with the
-\fBfconfigure\fR \fB\-translation binary\fR option, making the channel suitable for 
+\fBfconfigure\fR \fB\-translation binary\fR option, making the channel suitable for
 reading or writing of binary data.
 .PP
 In the second form, \fIaccess\fR consists of a list of any of the
@@ -382,7 +382,7 @@ pipe is closed.  These problems only occur because both Tcl and the child
 application are competing for the console at the same time.  If the command
 pipeline is started from a script, so that Tcl is not accessing the console,
 or if the command pipeline does not use standard input or output, but is
-redirected from or to a file, then the above problems do not occur.  
+redirected from or to a file, then the above problems do not occur.
 .RE
 .TP
 \fBUnix\fR\0\0\0\0\0\0\0
@@ -402,7 +402,7 @@ some will be sent to the Tcl evaluator.  This problem only occurs because
 both Tcl and the child application are competing for the console at the
 same time.  If the command pipeline is started from a script, so that Tcl is
 not accessing the console, or if the command pipeline does not use standard
-input, but is redirected from a file, then the above problem does not occur.  
+input, but is redirected from a file, then the above problem does not occur.
 .RE
 .PP
 See the \fBPORTABILITY ISSUES\fR section of the \fBexec\fR command for
index 07a3d47..a6a972f 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH package n 7.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -95,7 +95,7 @@ provided by a previous \fBpackage provide\fR command.
 If the \fIversion\fR argument is omitted, then the command
 returns the version number that is currently provided, or an
 empty string if no \fBpackage provide\fR command has been
-invoked for \fIpackage\fR in this interpreter.  
+invoked for \fIpackage\fR in this interpreter.
 .TP
 \fBpackage require \fR\fIpackage \fR?\fIrequirement...\fR?
 .
index c2f23ed..ec39be9 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH pkg_mkIndex n 8.3 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -47,7 +47,7 @@ interpreter and seeing what packages
 and new commands appear (this is why it is essential to have
 \fBpackage provide\fR commands or \fBTcl_PkgProvide\fR calls
 in the files, as described above).
-If you have a package split among scripts and binary files, 
+If you have a package split among scripts and binary files,
 or if you have dependencies among files,
 you may have to use the \fB\-load\fR option
 or adjust the order in which \fBpkg_mkIndex\fR processes
@@ -132,7 +132,7 @@ version control:  several versions of a package can be made available
 in the index files, with different applications using different
 versions based on \fBpackage require\fR commands.
 In contrast, \fBauto_mkindex\fR does not understand versions so
-it can only handle a single version of each package. 
+it can only handle a single version of each package.
 It is probably not a good idea to index a given package with both
 \fBpkg_mkIndex\fR and \fBauto_mkindex\fR.
 If you use \fBpkg_mkIndex\fR to index a package, its commands cannot
index 632485e..fdccaca 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH proc n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -32,10 +32,11 @@ elements specifies
 one argument.  Each argument specifier is also a list with either
 one or two fields.  If there is only a single field in the specifier
 then it is the name of the argument; if there are two fields, then
-the first is the argument name and the second is its default value. 
+the first is the argument name and the second is its default value.
 Arguments with default values that are followed by non-defaulted
-arguments become required arguments.  In 8.6 this will be considered an 
-error. 
+arguments become required arguments; enough actual arguments must be
+supplied to allow all arguments up to and including the last required
+formal argument.
 .PP
 When \fIname\fR is invoked a local variable
 will be created for each of the formal arguments to the procedure; its
@@ -46,13 +47,16 @@ Arguments with default values need not be
 specified in a procedure invocation.  However, there must be enough
 actual arguments for all the
 formal arguments that do not have defaults, and there must not be any extra
-actual arguments.  
+actual arguments.
 Arguments with default values that are followed by non-defaulted
-arguments become required arguments (in 8.6 it will be considered an 
-error).
+arguments become de-facto required arguments, though this may change
+in a future version of Tcl; portable code should ensure that all
+optional arguments come after all required arguments.
+.PP
 There is one special case to permit procedures with
 variable numbers of arguments.  If the last formal argument has the name
-\fBargs\fR, then a call to the procedure may contain more actual arguments
+.QW \fBargs\fR ,
+then a call to the procedure may contain more actual arguments
 than the procedure has formal arguments.  In this case, all of the actual arguments
 starting at the one that would be assigned to \fBargs\fR are combined into
 a list (as if the \fBlist\fR command had been used); this combined value
@@ -62,7 +66,7 @@ When \fIbody\fR is being executed, variable names normally refer to
 local variables, which are created automatically when referenced and
 deleted when the procedure returns.  One local variable is automatically
 created for each of the procedure's arguments.
-Other variables can only be accessed by invoking one of the \fBglobal\fR, 
+Other variables can only be accessed by invoking one of the \fBglobal\fR,
 \fBvariable\fR, \fBupvar\fR or \fBnamespace upvar\fR commands.
 The current namespace when \fIbody\fR is executed will be the
 namespace that the procedure's name exists in, which will be the
@@ -80,6 +84,20 @@ If an error occurs while executing the procedure
 body, then the procedure-as-a-whole will return that same error.
 .SH EXAMPLES
 .PP
+This is a procedure that takes two arguments and prints both their sum
+and their product. It also returns the string
+.QW OK
+to the caller as an explicit result.
+.PP
+.CS
+\fBproc\fR printSumProduct {x y} {
+    set sum [expr {$x + $y}]
+    set prod [expr {$x * $y}]
+    puts "sum is $sum, product is $prod"
+    return "OK"
+}
+.CE
+.PP
 This is a procedure that accepts arbitrarily many arguments and prints
 them out, one by one.
 .PP
index 87aa897..9a9a7e8 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH read n 8.1 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -58,12 +58,12 @@ configured to be nonblocking: \fBfconfigure\fI channelId \fB\-blocking
 \fI0\fR.  Then \fBread\fR behaves much like described above.  Care
 must be taken when using \fBread\fR on blocking serial ports:
 .TP
-\fBread \fIchannelId numChars\fR 
+\fBread \fIchannelId numChars\fR
 .
 In this form \fBread\fR blocks until \fInumChars\fR have been received
 from the serial port.
 .TP
-\fBread \fIchannelId\fR 
+\fBread \fIchannelId\fR
 .
 In this form \fBread\fR blocks until the reception of the end-of-file
 character, see \fBfconfigure\fR \fB\-eofchar\fR. If there no end-of-file
index 5fc2895..6f303a4 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH regexp n 8.3 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -51,7 +51,7 @@ the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
 .TP 15
 \fB\-indices\fR
 .
-Changes what is stored in the \fImatchVar\fR and \fIsubMatchVar\fRs. 
+Changes what is stored in the \fImatchVar\fR and \fIsubMatchVar\fRs.
 Instead of storing the matching characters from \fIstring\fR,
 each variable
 will contain a list of two decimal strings giving the indices
@@ -133,7 +133,7 @@ regular expression.  Examples are:
 \fB\-start\fR \fIindex\fR
 .
 Specifies a character index offset into the string to start
-matching the regular expression at.  
+matching the regular expression at.
 The \fIindex\fR value is interpreted in the same manner
 as the \fIindex\fR argument to \fBstring index\fR.
 When using this switch,
index ef4c289..a5b79de 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH regsub n 8.3 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -123,7 +123,7 @@ by \fIsubSpec\fR use the original unconverted form of \fIstring\fR.
 \fB\-start\fR \fIindex\fR
 .
 Specifies a character index offset into the string to start
-matching the regular expression at.  
+matching the regular expression at.
 The \fIindex\fR value is interpreted in the same manner
 as the \fIindex\fR argument to \fBstring index\fR.
 When using this switch,
index 383ed8c..ea590ea 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH return n 8.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -24,7 +24,7 @@ return \- Return from a procedure, or set return code of a script
 In its simplest usage, the \fBreturn\fR command is used without options
 in the body of a procedure to immediately return control to the caller
 of the procedure.  If a \fIresult\fR argument is provided, its value
-becomes the result of the procedure passed back to the caller.  
+becomes the result of the procedure passed back to the caller.
 If \fIresult\fR is not specified then an empty string will be returned
 to the caller as the result of the procedure.
 .PP
@@ -114,7 +114,7 @@ is meant to be additional information about the error,
 presented as a Tcl list for further processing by programs.
 If no \fB\-errorcode\fR option is provided to \fBreturn\fR when
 the \fB\-code error\fR option is provided, Tcl will set the value
-of the \fB\-errorcode\fR entry in the return options dictionary 
+of the \fB\-errorcode\fR entry in the return options dictionary
 to the default value of \fBNONE\fR.  The \fB\-errorcode\fR return
 option will also be stored in the global variable \fBerrorCode\fR.
 .TP
@@ -124,7 +124,7 @@ The \fB\-errorinfo\fR option receives special treatment only when the value
 of the \fB\-code\fR option is \fBTCL_ERROR\fR.  Then \fIinfo\fR is the initial
 stack trace, meant to provide to a human reader additional information
 about the context in which the error occurred.  The stack trace will
-also be stored in the global variable \fBerrorInfo\fR.  
+also be stored in the global variable \fBerrorInfo\fR.
 If no \fB\-errorinfo\fR option is provided to \fBreturn\fR when
 the \fB\-code error\fR option is provided, Tcl will provide its own
 initial stack trace value in the entry for \fB\-errorinfo\fR.  Tcl's
@@ -198,7 +198,7 @@ their documented interpretation in loops.
 .PP
 Procedure invocation also involves evaluation of a script, the body
 of the procedure.  Procedure invocation provides special treatment
-when evaluation of the procedure body returns the return code 
+when evaluation of the procedure body returns the return code
 \fBTCL_RETURN\fR.  In that circumstance, the \fB\-level\fR entry in the
 return options dictionary is decremented.  If after decrementing,
 the value of the \fB\-level\fR entry is 0, then the value of
@@ -231,7 +231,7 @@ procedure, interrupting the procedure body.
 .CS
 proc printOneLine {} {
     puts "line 1"    ;# This line will be printed.
-    \fBreturn\fR               
+    \fBreturn\fR
     puts "line 2"    ;# This line will not be printed.
 }
 .CE
index 76184a5..b39f2c2 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH "Safe Tcl" n 8.0 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -53,8 +53,8 @@ No knowledge of the file system structure is leaked to the
 safe interpreter, because it has access only to a virtualized path
 containing tokens. When the safe interpreter requests to source a file, it
 uses the token in the virtual path as part of the file name to source; the
-master interpreter transparently 
-translates the token into a real directory name and executes the 
+master interpreter transparently
+translates the token into a real directory name and executes the
 requested operation (see the section \fBSECURITY\fR below for details).
 Different levels of security can be selected by using the optional flags
 of the commands described below.
@@ -81,7 +81,7 @@ other means, like \fBinterp create\fR \fB\-safe\fR.
 \fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
 If no \fIoptions\fR are given, returns the settings for all options for the
 named safe interpreter as a list of options and their current values
-for that \fIslave\fR. 
+for that \fIslave\fR.
 If a single additional argument is provided,
 it will return a list of 2 elements \fIname\fR and \fIvalue\fR where
 \fIname\fR is the full name of that option and \fIvalue\fR the current value
@@ -106,7 +106,7 @@ safe::interpConfigure $i0  \-delete {foo bar} \-statics 0
 .RE
 .TP
 \fB::safe::interpDelete\fR \fIslave\fR
-Deletes the safe interpreter and cleans up the corresponding  
+Deletes the safe interpreter and cleans up the corresponding
 master interpreter data structures.
 If a \fIdeleteHook\fR script was specified for this interpreter it is
 evaluated before the interpreter is deleted, with the name of the
@@ -175,26 +175,26 @@ ERROR for slave interp10 : /foo/bar/init.tcl: no such file or directory
 .CE
 .RE
 .SS OPTIONS
-The following options are common to 
-\fB::safe::interpCreate\fR, \fB::safe::interpInit\fR, 
+The following options are common to
+\fB::safe::interpCreate\fR, \fB::safe::interpInit\fR,
 and \fB::safe::interpConfigure\fR.
-Any option name can be abbreviated to its minimal 
+Any option name can be abbreviated to its minimal
 non-ambiguous name.
 Option names are not case sensitive.
-.TP 
+.TP
 \fB\-accessPath\fR \fIdirectoryList\fR
 This option sets the list of directories from which the safe interpreter
 can \fBsource\fR and \fBload\fR files.
 If this option is not specified, or if it is given as the
 empty list, the safe interpreter will use the same directories as its
 master for auto-loading.
-See the section \fBSECURITY\fR below for more detail about virtual paths, 
+See the section \fBSECURITY\fR below for more detail about virtual paths,
 tokens and access control.
 .TP
 \fB\-statics\fR \fIboolean\fR
 This option specifies if the safe interpreter will be allowed
 to load statically linked packages (like \fBload {} Tk\fR).
-The default value is \fBtrue\fR : 
+The default value is \fBtrue\fR :
 safe interpreters are allowed to load statically linked packages.
 .TP
 \fB\-noStatics\fR
@@ -205,7 +205,7 @@ to load statically linked packages.
 \fB\-nested\fR \fIboolean\fR
 This option specifies if the safe interpreter will be allowed
 to load packages into its own sub-interpreters.
-The default value is \fBfalse\fR : 
+The default value is \fBfalse\fR :
 safe interpreters are not allowed to load packages into
 their own sub-interpreters.
 .TP
@@ -213,7 +213,7 @@ their own sub-interpreters.
 This option is a convenience shortcut for \fB\-nested true\fR and
 thus specifies the safe interpreter will be allowed
 to load packages into its own sub-interpreters.
-.TP 
+.TP
 \fB\-deleteHook\fR \fIscript\fR
 When this option is given a non-empty \fIscript\fR, it will be
 evaluated in the master with the name of
@@ -286,17 +286,17 @@ This virtual path system is maintained in the master interpreter for each safe
 interpreter created by \fB::safe::interpCreate\fR or initialized by
 \fB::safe::interpInit\fR and
 the path maps tokens accessible in the safe interpreter into real path
-names on the local file system thus preventing safe interpreters 
+names on the local file system thus preventing safe interpreters
 from gaining knowledge about the
 structure of the file system of the host on which the interpreter is
 executing.
 The only valid file names arguments
 for the \fBsource\fR and \fBload\fR aliases provided to the slave
-are path in the form of 
+are path in the form of
 \fB[file join \fItoken filename\fB]\fR (i.e. when using the
 native file path formats: \fItoken\fB/\fIfilename\fR
 on Unix and \fItoken\fB\e\fIfilename\fR on Windows),
-where \fItoken\fR is representing one of the directories 
+where \fItoken\fR is representing one of the directories
 of the \fIaccessPath\fR list and \fIfilename\fR is
 one file in that directory (no sub directories access are allowed).
 .PP
@@ -323,25 +323,25 @@ list will be assigned a token that will be set in
 the slave \fBauto_path\fR and the first element of that list will be set as
 the \fBtcl_library\fR for that slave.
 .PP
-If the access path argument is not given or is the empty list, 
+If the access path argument is not given or is the empty list,
 the default behavior is to let the slave access the same packages
-as the master has access to (Or to be more precise: 
+as the master has access to (Or to be more precise:
 only packages written in Tcl (which by definition cannot be dangerous
 as they run in the slave interpreter) and C extensions that
-provides a _SafeInit entry point). For that purpose, the master's 
-\fBauto_path\fR will be used to construct the slave access path. 
+provides a _SafeInit entry point). For that purpose, the master's
+\fBauto_path\fR will be used to construct the slave access path.
 In order that the slave successfully loads the Tcl library files
 (which includes the auto-loading mechanism itself) the \fBtcl_library\fR will be
-added or moved to the first position if necessary, in the 
+added or moved to the first position if necessary, in the
 slave access path, so the slave
 \fBtcl_library\fR will be the same as the master's (its real
-path will still be invisible to the slave though). 
+path will still be invisible to the slave though).
 In order that auto-loading works the same for the slave and
 the master in this by default case, the first-level
 sub directories of each directory in the master \fBauto_path\fR will
 also be added (if not already included) to the slave access path.
 You can always specify a more
-restrictive path for which sub directories will never be searched by 
+restrictive path for which sub directories will never be searched by
 explicitly specifying your directory list with the \fB\-accessPath\fR flag
 instead of relying on this default mechanism.
 .PP
index 5b91449..d963d6c 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH scan n 8.4 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -37,7 +37,7 @@ performed.
 If the next character in \fIformat\fR is a blank or tab then it
 matches any number of white space characters in \fIstring\fR (including
 zero).
-Otherwise, if it is not a \fB%\fR character then it 
+Otherwise, if it is not a \fB%\fR character then it
 must match the next character of \fIstring\fR.
 When a \fB%\fR is encountered in \fIformat\fR, it indicates
 the start of a conversion specifier.
@@ -52,7 +52,7 @@ The fields that are present must appear in the order given above.
 When \fBscan\fR finds a conversion specifier in \fIformat\fR, it
 first skips any white-space characters in \fIstring\fR (unless the
 conversion character is \fB[\fR or \fBc\fR).
-Then it converts the next input characters according to the 
+Then it converts the next input characters according to the
 conversion specifier and stores the result in the variable given
 by the next argument to \fBscan\fR.
 .SS "OPTIONAL POSITIONAL SPECIFIER"
@@ -95,7 +95,7 @@ truncated as required by the size modifier value.
 .TP
 \fBo\fR
 .
-The input substring must be an octal integer. It is read in and the 
+The input substring must be an octal integer. It is read in and the
 integer value is stored in the variable,
 truncated as required by the size modifier value.
 .TP
@@ -130,22 +130,22 @@ truncated as required by the size modifier value.
 .TP
 \fBc\fR
 .
-A single character is read in and its Unicode value is stored in 
+A single character is read in and its Unicode value is stored in
 the variable as an integer value.
 Initial white space is not skipped in this case, so the input
 substring may be a white-space character.
 .TP
 \fBs\fR
 .
-The input substring consists of all the characters up to the next 
+The input substring consists of all the characters up to the next
 white-space character; the characters are copied to the variable.
 .TP
 \fBe\fR or \fBf\fR or \fBg\fR or \fBE\fR or \fBG\fR
 .
-The input substring must be a floating-point number consisting 
+The input substring must be a floating-point number consisting
 of an optional sign, a string of decimal digits possibly
-containing a decimal point, and an optional exponent consisting 
-of an \fBe\fR or \fBE\fR followed by an optional sign and a string of 
+containing a decimal point, and an optional exponent consisting
+of an \fBe\fR or \fBE\fR followed by an optional sign and a string of
 decimal digits.
 It is read in and stored in the variable as a floating-point value.
 .TP
@@ -166,8 +166,8 @@ it is treated as part of \fIchars\fR rather than indicating a range.
 .
 The input substring consists of one or more characters not in \fIchars\fR.
 The matching string is stored in the variable.
-If the character immediately following the \fB^\fR is a \fB]\fR then it is 
-treated as part of the set rather than the closing bracket for 
+If the character immediately following the \fB^\fR is a \fB]\fR then it is
+treated as part of the set rather than the closing bracket for
 the set.
 If \fIchars\fR
 contains a sequence of the form \fIa\fB\-\fIb\fR then any
@@ -183,12 +183,12 @@ of characters scanned from the input string so far is stored in the variable.
 .PP
 The number of characters read from the input for a conversion is the
 largest number that makes sense for that particular conversion (e.g.
-as many decimal digits as possible for \fB%d\fR, as 
+as many decimal digits as possible for \fB%d\fR, as
 many octal digits as possible for \fB%o\fR, and so on).
 The input substring for a given conversion terminates either when a
-white-space character is encountered or when the maximum substring 
+white-space character is encountered or when the maximum substring
 width has been reached, whichever comes first.
-If a \fB*\fR is present in the conversion specifier 
+If a \fB*\fR is present in the conversion specifier
 then no variable is assigned and the next scan argument is not consumed.
 .SH "DIFFERENCES FROM ANSI SSCANF"
 .PP
index 545b15f..f065087 100644 (file)
--- a/doc/set.n
+++ b/doc/set.n
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH set n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -29,14 +29,14 @@ Otherwise \fIvarName\fR refers to a scalar variable.
 If \fIvarName\fR includes namespace qualifiers
 (in the array name if it refers to an array element), or if \fIvarName\fR
 is unqualified (does not include the names of any containing namespaces)
-but no procedure is active, 
+but no procedure is active,
 \fIvarName\fR refers to a namespace variable
 resolved according to the rules described under \fBNAME RESOLUTION\fR in
 the \fBnamespace\fR manual page.
 .PP
 If a procedure is active and \fIvarName\fR is unqualified, then
 \fIvarName\fR refers to a parameter or local variable of the procedure,
-unless \fIvarName\fR was declared to resolve differently through one of the 
+unless \fIvarName\fR was declared to resolve differently through one of the
 \fBglobal\fR, \fBvariable\fR or \fBupvar\fR commands.
 .SH EXAMPLES
 .PP
index 275771d..3efdb37 100644 (file)
@@ -98,9 +98,9 @@ asynchronous connection has succeeded or failed. See the \fBvwait\fR
 and the \fBchan\fR commands for more details on the event loop and
 channel events.
 .PP
-The \fBchan configure\fR option \fB-connecting\fR may be used to check if the connect is still running. To verify a successful connect, the option \fB-error\fR may be checked when \fB-connecting\fR returned 0. 
+The \fBchan configure\fR option \fB-connecting\fR may be used to check if the connect is still running. To verify a successful connect, the option \fB-error\fR may be checked when \fB-connecting\fR returned 0.
 .PP
-Operation without the event queue requires at the moment calls to \fBchan configure\fR to advance the internal state machine. 
+Operation without the event queue requires at the moment calls to \fBchan configure\fR to advance the internal state machine.
 .RE
 .SH "SERVER SOCKETS"
 .PP
index 33780ff..00ce85c 100644 (file)
@@ -4,7 +4,7 @@
 .\"
 .\" See the file "license.terms" for information on usage and redistribution
 .\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-.\" 
+.\"
 .TH string n 8.1 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -443,7 +443,7 @@ would refer to the
 in
 .QW abcd ).
 .IP \fIM\fB+\fIN\fR 10
-The char specified at the integral index that is the sum of 
+The char specified at the integral index that is the sum of
 integer values \fIM\fR and \fIN\fR (e.g.,
 .QW \fB1+1\fR
 would refer to the
@@ -451,7 +451,7 @@ would refer to the
 in
 .QW abcd ).
 .IP \fIM\fB\-\fIN\fR 10
-The char specified at the integral index that is the difference of 
+The char specified at the integral index that is the difference of
 integer values \fIM\fR and \fIN\fR (e.g.,
 .QW \fB2\-1\fR
 would refer to the
index 990b9d3..4518140 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH subst n 7.4 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -33,7 +33,7 @@ For example, if \fB\-nocommands\fR is specified, command substitution
 is not performed:  open and close brackets are treated as ordinary characters
 with no special interpretation.
 .PP
-Note that the substitution of one kind can include substitution of 
+Note that the substitution of one kind can include substitution of
 other kinds.  For example, even when the \fB\-novariables\fR option
 is specified, command substitution is performed without restriction.
 This means that any variable substitution necessary to complete the
index 29265be..05c1922 100644 (file)
@@ -7,7 +7,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH "tcltest" n 2.3 tcltest "Tcl Bundled Packages"
 .so man.macros
 .BS
@@ -118,7 +118,7 @@ all \fIoption\fRs begin with
 .TP
 \fBloadTestedCommands\fR
 .
-Evaluates in the caller's context the script specified by 
+Evaluates in the caller's context the script specified by
 \fBconfigure \-load\fR or \fBconfigure \-loadfile\fR.
 Returns the result of that script evaluation, including any error
 raised by the script.  Use this command and the related
@@ -486,7 +486,7 @@ test, typically test failure messages.  Good \fIdescription\fR values
 should briefly explain the purpose of the test to users of a test suite.
 The name of a Tcl or C function being tested should be included in the
 description for regression tests.  If the test case exists to reproduce
-a bug, include the bug ID in the description. 
+a bug, include the bug ID in the description.
 .PP
 Valid attributes and associated values are:
 .TP
@@ -508,8 +508,8 @@ should be accomplished by the \fB\-constraints\fR option, not by
 conditional evaluation of \fBtest\fR.  In that way, the same
 number of tests are always reported by the test suite, though
 the number skipped may change based on the testing environment.
-The default value is an empty list.  
-See \fBTEST CONSTRAINTS\fR below for a list of built-in constraints 
+The default value is an empty list.
+See \fBTEST CONSTRAINTS\fR below for a list of built-in constraints
 and information on how to add your own constraints.
 .TP
 \fB\-setup \fIscript\fR
@@ -521,7 +521,7 @@ is an empty script.
 .TP
 \fB\-body \fIscript\fR
 .
-The \fB\-body\fR attribute indicates the \fIscript\fR to run to carry out the 
+The \fB\-body\fR attribute indicates the \fIscript\fR to run to carry out the
 test, which must return a result that can be checked for correctness.
 If evaluation of \fIscript\fR raises an error, the test will fail
 (unless the \fB\-returnCodes\fR option is used to state that an error
@@ -561,7 +561,7 @@ processed for comparison.
 \fB\-errorOutput \fIexpectedValue\fR
 .
 The \fB\-errorOutput\fR attribute supplies the \fIexpectedValue\fR against
-which any output sent to \fBstderr\fR or \fBerrorChannel\fR during 
+which any output sent to \fBstderr\fR or \fBerrorChannel\fR during
 evaluation of the script(s) will be compared. Note that only output
 printed using the global \fBputs\fR command is used for comparison.  If
 \fB\-errorOutput\fR is not specified, output sent to \fBstderr\fR and
@@ -661,7 +661,7 @@ This test can only be run on a Mac or Unix platform.
 \fItempNotWin\fR
 .
 This test can not be run on Windows.  This flag is used to temporarily
-disable a test. 
+disable a test.
 .TP
 \fItempNotMac\fR
 .
@@ -671,17 +671,17 @@ to temporarily disable a test.
 \fIunixCrash\fR
 .
 This test crashes if it is run on Unix.  This flag is used to temporarily
-disable a test. 
+disable a test.
 .TP
 \fIwinCrash\fR
 .
 This test crashes if it is run on Windows.  This flag is used to temporarily
-disable a test. 
+disable a test.
 .TP
 \fImacCrash\fR
 .
 This test crashes if it is run on a Mac.  This flag is used to temporarily
-disable a test. 
+disable a test.
 .TP
 \fIemptyTest\fR
 .
@@ -702,17 +702,17 @@ This test can only be run in some known development environment.
 Some tests are inherently non-portable because they depend on things
 like word length, file system configuration, window manager, etc.
 This constraint has value false to cause tests to be skipped unless
-the user specifies otherwise.  
+the user specifies otherwise.
 .TP
 \fIuserInteraction\fR
 .
 This test requires interaction from the user.  This constraint has
 value false to causes tests to be skipped unless the user specifies
-otherwise.  
+otherwise.
 .TP
 \fIinteractive\fR
 .
-This test can only be run in if the interpreter is in interactive mode 
+This test can only be run in if the interpreter is in interactive mode
 (when the global tcl_interactive variable is set to 1).
 .TP
 \fInonBlockFiles\fR
@@ -792,7 +792,7 @@ and sorted.  Then each file will be evaluated in turn.  If
 be \fBsource\fRd in the caller's context.  If it is false,
 then a copy of \fBinterpreter\fR will be \fBexec\fR'd to
 evaluate each file.  The multi-process operation is useful
-when testing can cause errors so severe that a process 
+when testing can cause errors so severe that a process
 terminates.  Although such an error may terminate a child
 process evaluating one file, the master process can continue
 with the rest of the test suite.  In multi-process operation,
@@ -872,10 +872,10 @@ harness are doing.
 .
 Sets the type of output verbosity desired to \fIlevel\fR,
 a list of zero or more of the elements \fBbody\fR, \fBpass\fR,
-\fBskip\fR, \fBstart\fR, \fBerror\fR and \fBline\fR.  Default value
-is
+\fBskip\fR, \fBstart\fR, \fBerror\fR, \fBline\fR, \fBmsec\fR and \fBusec\fR.
+Default value is
 .QW "\fBbody error\fR" .
-Levels are defined as: 
+Levels are defined as:
 .RS
 .IP "body (\fBb\fR)"
 Display the body of failed tests
@@ -890,6 +890,16 @@ Print errorInfo and errorCode, if they exist, when a test return code
 does not match its expected return code
 .IP "line (\fBl\fR)"
 Print source file line information of failed tests
+.IP "msec (\fBm\fR)"
+Print each test's execution time in milliseconds
+.IP "usec (\fBu\fR)"
+Print each test's execution time in microseconds
+.PP
+Note that the \fBmsec\fR and \fBusec\fR verbosity levels are provided as
+indicative measures only. They do not tackle the problem of repeatibility which
+should be considered in performance tests or benchmarks. To use these verbosity
+levels to thoroughly track performance degradations, consider wrapping your
+test bodies with \fBtime\fR commands.
 .PP
 The single letter abbreviations noted above are also recognized
 so that
@@ -911,7 +921,7 @@ test files have been evaluated.
 .IP 1
 Also check for core files at the end of each \fBtest\fR command.
 .IP 2
-Check for core files at all times described above, and save a 
+Check for core files at all times described above, and save a
 copy of each core file produced in \fBconfigure \-tmpdir\fR.
 .RE
 .TP
@@ -988,7 +998,7 @@ Sets the filename from which to read a script to be evaluated
 by \fBloadTestedCommands\fR.  This is an alternative to
 \fB\-load\fR.  They cannot be used together.
 .TP
-\fB\-outfile \fIfilename\fR 
+\fB\-outfile \fIfilename\fR
 .
 Sets the file to which all output produced by tcltest should be
 written.  A file named \fIfilename\fR will be \fBopen\fRed for writing,
@@ -1065,7 +1075,7 @@ used by \fBrunAllTests\fR to find test files.  It is a good rule of
 thumb to have one test file for each source code file of your project.
 It is good practice to edit the test file and the source code file
 together, keeping tests synchronized with code changes.
-.PP 
+.PP
 Most of the code in the test file should be the \fBtest\fR commands.
 Use constraints to skip tests, rather than conditional evaluation
 of \fBtest\fR.
@@ -1199,7 +1209,7 @@ to establish a configuration from command line arguments.
 There are two known issues related to nested evaluations of \fBtest\fR.
 The first issue relates to the stack level in which test scripts are
 executed.  Tests nested within other tests may be executed at the same
-stack level as the outermost test.  For example, in the following code: 
+stack level as the outermost test.  For example, in the following code:
 .PP
 .CS
 \fBtest\fR level-1.1 {level 1} {
@@ -1211,7 +1221,7 @@ stack level as the outermost test.  For example, in the following code:
 .CE
 .PP
 any script executed in level-2.1 may be executed at the same stack
-level as the script defined for level-1.1.  
+level as the script defined for level-1.1.
 .PP
 In addition, while two \fBtest\fRs have been run, results will only
 be reported by \fBcleanupTests\fR for tests at the same level as
@@ -1241,7 +1251,7 @@ script is being run.  Errors thrown by C procedures or printed
 directly from C applications will not be caught by the \fBtest\fR command.
 Therefore, usage of the \fB\-output\fR and \fB\-errorOutput\fR
 options to \fBtest\fR is useful only for pure Tcl applications
-that use \fBputs\fR to produce output. 
+that use \fBputs\fR to produce output.
 .SH KEYWORDS
 test, test harness, test suite
 .\" Local Variables:
index a256c21..adefe40 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH tclvars n 8.0 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -94,7 +94,7 @@ Note that this environment variable should \fInot\fR normally be set.
 \fBenv(TCLLIBPATH)\fR
 .
 If set, then it must contain a valid Tcl list giving directories to
-search during auto-load operations.  Directories must be specified in 
+search during auto-load operations.  Directories must be specified in
 Tcl format, using
 .QW /
 as the path separator, regardless of platform.
@@ -229,7 +229,7 @@ nested Tcl commands that had been invoked at the time of the error.
 This variable holds the name of a directory containing the
 system library of Tcl scripts, such as those used for auto-loading.
 The value of this variable is returned by the \fBinfo library\fR command.
-See the \fBlibrary\fR manual entry for details of the facilities 
+See the \fBlibrary\fR manual entry for details of the facilities
 provided by the Tcl script library.
 Normally each application or package will have its own application-specific
 script library in addition to the Tcl script library;
@@ -289,7 +289,7 @@ predefined elements are:
 \fBbyteOrder\fR
 .
 The native byte order of this machine: either \fBlittleEndian\fR or
-\fBbigEndian\fR. 
+\fBbigEndian\fR.
 .TP
 \fBdebug\fR
 .
@@ -376,7 +376,7 @@ binary number.
 .PP
 .RS
 If \fBtcl_precision\fR is not zero, then when Tcl converts a floating
-point number, it creates a decimal representation of at most 
+point number, it creates a decimal representation of at most
 \fBtcl_precision\fR significant digits; the result may be shorter if
 the shorter result represents the original number exactly. If no
 result of at most \fBtcl_precision\fR digits is an exact representation
index 4ae7e19..5482e59 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH trace n "8.4" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index e00aa84..4da74f2 100644 (file)
@@ -1,4 +1,4 @@
-'\" 
+'\"
 '\" Copyright (c) 2008 Donal K. Fellows
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
index 834ccc1..eae4dc7 100644 (file)
--- a/doc/try.n
+++ b/doc/try.n
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH try n 8.6 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index cdfbe43..82dcefc 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH unknown n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -21,14 +21,14 @@ tries to invoke a command that does not exist.  The default implementation
 of \fBunknown\fR is a library procedure defined when Tcl initializes an
 interpreter.  You can override the default \fBunknown\fR to change its
 functionality, or you can register a new handler for individual namespaces
-using the \fBnamespace unknown\fR command.  Note that there is no default 
+using the \fBnamespace unknown\fR command.  Note that there is no default
 implementation of \fBunknown\fR in a safe interpreter.
 .PP
 If the Tcl interpreter encounters a command name for which there
-is not a defined command (in either the current namespace, or the 
+is not a defined command (in either the current namespace, or the
 global namespace), then Tcl checks for the existence of
 an unknown handler for the current namespace. By default, this
-handler is a command named \fB::unknown\fR.  If there is no such 
+handler is a command named \fB::unknown\fR.  If there is no such
 command, then the interpreter returns an error.
 If the \fBunknown\fR command exists (or a new handler has been
 registered for the current namespace), then it is invoked with
index febd694..0a8e99b 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH unload n 8.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -45,7 +45,7 @@ never report an error.
 \fB\-keeplibrary\fR
 .
 This switch will prevent \fBunload\fR from issuing the operating system call
-that will unload the library from the process. 
+that will unload the library from the process.
 .TP
 \fB\-\|\-\fR
 .
@@ -109,7 +109,7 @@ the library is used by other interpreters),
 \fBTCL_UNLOAD_DETACH_FROM_INTERPRETER\fR will be defined. However, if the
 library is used only by the target interpreter and the library will be
 detached from the application as soon as the unload procedure returns,
-the \fIflags\fR argument will be set to \fBTCL_UNLOAD_DETACH_FROM_PROCESS\fR. 
+the \fIflags\fR argument will be set to \fBTCL_UNLOAD_DETACH_FROM_PROCESS\fR.
 .SS NOTES
 .PP
 The \fBunload\fR command cannot unload libraries that are statically
index 8b63959..2cfc63e 100644 (file)
@@ -5,7 +5,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH unset n 8.4 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index 875172a..ce0fb25 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH update n 7.5 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index a96f729..4decc6d 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH uplevel n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index 380a390..91defe6 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH upvar n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index 7d58a02..a6e545f 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH variable n 8.0 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index c9b51ab..f64d39c 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH vwait n 8.0 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index 60275e8..961260c 100644 (file)
@@ -4,7 +4,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH while n "" Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
index b8d0ee5..fd29e0d 100644 (file)
@@ -3,7 +3,7 @@
 '\"
 '\" See the file "license.terms" for information on usage and redistribution
 '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\" 
+'\"
 .TH zlib n 8.6 Tcl "Tcl Built-In Commands"
 .so man.macros
 .BS
@@ -81,7 +81,7 @@ named by the \fBfilename\fR field was modified. Suitable for use with
 The type of the uncompressed data (\fBbinary\fR or \fBtext\fR) if known.
 .RE
 .TP
-\fBzlib gzip\fI string\fR ?\fB\-level \fIlevel\fR? ?\fB\-header \fIdict\fR? 
+\fBzlib gzip\fI string\fR ?\fB\-level \fIlevel\fR? ?\fB\-header \fIdict\fR?
 .
 Return the compressed contents of binary string \fIstring\fR in gzip format.
 If \fB\-level\fR is given, \fIlevel\fR gives the compression level to use
@@ -174,7 +174,11 @@ to the \fBzlib push\fR command:
 .VS "TIP 400"
 Sets the compression dictionary to use when working with compressing or
 decompressing the data to be \fIbinData\fR. Not valid for transformations that
-work with gzip-format data.
+work with gzip-format data.  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. Tcl provides no mechanism for choosing a good such dictionary for
+a particular data sequence.
 .VE
 .TP
 \fB\-header\fI dictionary\fR
@@ -207,11 +211,13 @@ compression algorithm depends on what format is being produced or consumed.
 .TP
 \fB\-dictionary\fI binData\fR
 .VS "TIP 400"
-This read-write options gets or sets the compression dictionary to use when
-working with compressing or decompressing the data to be \fIbinData\fR. It is
-not valid for transformations that work with gzip-format data, and should not
-normally be set on compressing transformations other than at the point where
-the transformation is stacked.
+This read-write options gets or sets the initial compression dictionary to use
+when working with compressing or decompressing the data to be \fIbinData\fR.
+It is not valid for transformations that work with gzip-format data, and should
+not normally be set on compressing transformations other than at the point where
+the transformation is stacked. Note that this cannot be used to get the
+current active compression dictionary mid-stream, as that information is not
+exposed by the underlying library.
 .VE
 .TP
 \fB\-flush\fI type\fR
index 16e3ae9..affcb48 100644 (file)
@@ -256,20 +256,33 @@ static const chr brbacks[] = {    /* \s within brackets */
     CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
     CHR(':'), CHR(']')
 };
+
+#define PUNCT_CONN \
+       CHR('_'), \
+       0x203f /* UNDERTIE */, \
+       0x2040 /* CHARACTER TIE */,\
+       0x2054 /* INVERTED UNDERTIE */,\
+       0xfe33 /* PRESENTATION FORM FOR VERTICAL LOW LINE */, \
+       0xfe34 /* PRESENTATION FORM FOR VERTICAL WAVY LOW LINE */, \
+       0xfe4d /* DASHED LOW LINE */, \
+       0xfe4e /* CENTRELINE LOW LINE */, \
+       0xfe4f /* WAVY LOW LINE */, \
+       0xff3f /* FULLWIDTH LOW LINE */
+
 static const chr backw[] = {   /* \w */
     CHR('['), CHR('['), CHR(':'),
     CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
-    CHR(':'), CHR(']'), CHR('_'), CHR(']')
+    CHR(':'), CHR(']'), PUNCT_CONN, CHR(']')
 };
 static const chr backW[] = {   /* \W */
     CHR('['), CHR('^'), CHR('['), CHR(':'),
     CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
-    CHR(':'), CHR(']'), CHR('_'), CHR(']')
+    CHR(':'), CHR(']'), PUNCT_CONN, CHR(']')
 };
 static const chr brbackw[] = { /* \w within brackets */
     CHR('['), CHR(':'),
     CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
-    CHR(':'), CHR(']'), CHR('_')
+    CHR(':'), CHR(']'), PUNCT_CONN
 };
 \f
 /*
index 3c10cb6..a6958fe 100644 (file)
@@ -140,35 +140,36 @@ static const crange alphaRangeTable[] = {
     {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
     {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
     {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
-    {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x904, 0x939},
-    {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c}, {0x993, 0x9a8},
-    {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1}, {0xa05, 0xa0a},
-    {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c}, {0xa72, 0xa74},
-    {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
-    {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
-    {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, {0xb8e, 0xb90},
-    {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xc05, 0xc0c},
-    {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc58, 0xc5a},
-    {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
-    {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a},
-    {0xd5f, 0xd61}, {0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1},
-    {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46},
-    {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0},
-    {0xec0, 0xec4}, {0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c},
-    {0xf88, 0xf8c}, {0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d},
-    {0x106e, 0x1070}, {0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa},
-    {0x10fc, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d},
-    {0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5},
-    {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310},
-    {0x1312, 0x1315}, {0x1318, 0x135a}, {0x1380, 0x138f}, {0x13a0, 0x13f5},
-    {0x13f8, 0x13fd}, {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a},
-    {0x16a0, 0x16ea}, {0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711},
-    {0x1720, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770},
-    {0x1780, 0x17b3}, {0x1820, 0x1877}, {0x1880, 0x18a8}, {0x18b0, 0x18f5},
-    {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
-    {0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
-    {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23},
-    {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1},
+    {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x8b6, 0x8bd},
+    {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c},
+    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1},
+    {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c},
+    {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
+    {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28},
+    {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a},
+    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
+    {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39},
+    {0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8},
+    {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
+    {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61}, {0xd7a, 0xd7f},
+    {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6},
+    {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f},
+    {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf},
+    {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a},
+    {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081},
+    {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248}, {0x124a, 0x124d},
+    {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
+    {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
+    {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
+    {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1401, 0x166c},
+    {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8},
+    {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751},
+    {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877},
+    {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e},
+    {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
+    {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b},
+    {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f},
+    {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1},
     {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
     {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
     {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3},
@@ -183,7 +184,7 @@ static const crange alphaRangeTable[] = {
     {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5},
     {0x4e00, 0x9fd5}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c},
     {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5},
-    {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ad}, {0xa7b0, 0xa7b7},
+    {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae}, {0xa7b0, 0xa7b7},
     {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822},
     {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925},
     {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4},
@@ -193,6 +194,8 @@ static const crange alphaRangeTable[] = {
     {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
     {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, {0xac00, 0xd7a3},
     {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e},
+    {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e},
+    {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e}, {0xde40, 0xde7e},
     {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e},
     {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
     {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36},
@@ -205,36 +208,38 @@ static const crange alphaRangeTable[] = {
     {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
     {0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
     {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d},
-    {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
-    {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
-    {0x10860, 0x10876}, {0x10880, 0x1089e}, {0x108e0, 0x108f2}, {0x10900, 0x10915},
-    {0x10920, 0x10939}, {0x10980, 0x109b7}, {0x10a10, 0x10a13}, {0x10a15, 0x10a17},
-    {0x10a19, 0x10a33}, {0x10a60, 0x10a7c}, {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7},
-    {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72},
-    {0x10b80, 0x10b91}, {0x10c00, 0x10c48}, {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2},
-    {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8}, {0x11103, 0x11126},
-    {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, {0x11200, 0x11211},
-    {0x11213, 0x1122b}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d},
-    {0x1129f, 0x112a8}, {0x112b0, 0x112de}, {0x11305, 0x1130c}, {0x11313, 0x11328},
-    {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361}, {0x11480, 0x114af},
+    {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563},
+    {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
+    {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e},
+    {0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7},
+    {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c},
+    {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
+    {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48},
+    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af},
+    {0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
+    {0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
+    {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
+    {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
+    {0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
     {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
-    {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x12000, 0x12399},
-    {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38},
-    {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43},
-    {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
-    {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
-    {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
-    {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
-    {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
-    {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0}, {0x1d6c2, 0x1d6da},
-    {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e},
-    {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2},
-    {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f},
-    {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a},
-    {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89},
-    {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb},
-    {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1},
-    {0x2f800, 0x2fa1d}
+    {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08},
+    {0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {0x12000, 0x12399}, {0x12480, 0x12543},
+    {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
+    {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
+    {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, {0x17000, 0x187ec},
+    {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
+    {0x1bc90, 0x1bc99}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
+    {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
+    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
+    {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0},
+    {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734},
+    {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8},
+    {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943},
+    {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
+    {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
+    {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
+    {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
+    {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}
 #endif
 };
 
@@ -249,24 +254,24 @@ static const chr alphaCharTable[] = {
     0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xaf9,
     0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83,
     0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d,
-    0xc60, 0xc61, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2, 0xd3d,
-    0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87, 0xe88,
-    0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3, 0xebd,
-    0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7, 0x10cd,
-    0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 0x1baf, 0x1cf5,
-    0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102, 0x2107,
-    0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2, 0x2cf3,
-    0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c, 0xa62a,
-    0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6, 0xaac0,
-    0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
+    0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2,
+    0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87,
+    0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3,
+    0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7,
+    0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 0x1baf,
+    0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102,
+    0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2,
+    0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c,
+    0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6,
+    0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
 #if TCL_UTF_MAX > 4
     ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
     0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332,
-    0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x16f50,
-    0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546,
-    0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49,
-    0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f,
-    0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
+    0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11c40,
+    0x16f50, 0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6,
+    0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
+    0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
+    0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
 #endif
 };
 
@@ -289,7 +294,7 @@ static const crange controlRangeTable[] = {
 #define NUM_CONTROL_RANGE (sizeof(controlRangeTable)/sizeof(crange))
 
 static const chr controlCharTable[] = {
-    0xad, 0x61c, 0x6dd, 0x70f, 0x180e, 0xfeff
+    0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff
 #if TCL_UTF_MAX > 4
     ,0x110bd, 0xe0001
 #endif
@@ -314,9 +319,10 @@ static const crange digitRangeTable[] = {
     {0xff10, 0xff19}
 #if TCL_UTF_MAX > 4
     ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
-    {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x114d0, 0x114d9}, {0x11650, 0x11659},
-    {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9}, {0x16a60, 0x16a69},
-    {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}
+    {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9},
+    {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9},
+    {0x11c50, 0x11c59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff},
+    {0x1e950, 0x1e959}
 #endif
 };
 
@@ -339,7 +345,7 @@ static const crange punctRangeTable[] = {
     {0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7},
     {0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e},
     {0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998},
-    {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e42},
+    {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e44},
     {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
     {0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
     {0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
@@ -348,9 +354,9 @@ static const crange punctRangeTable[] = {
 #if TCL_UTF_MAX > 4
     ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
     {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
-    {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x115c1, 0x115d7},
-    {0x11641, 0x11643}, {0x1173c, 0x1173e}, {0x12470, 0x12474}, {0x16b37, 0x16b3b},
-    {0x1da87, 0x1da8b}
+    {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
+    {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
+    {0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
 #endif
 };
 
@@ -371,8 +377,8 @@ static const chr punctCharTable[] = {
     0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
 #if TCL_UTF_MAX > 4
     ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
-    0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x114c6, 0x16a6e, 0x16a6f, 0x16af5,
-    0x16b44, 0x1bc9f
+    0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
+    0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f
 #endif
 };
 
@@ -404,24 +410,24 @@ static const crange lowerRangeTable[] = {
     {0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
     {0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
     {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd},
-    {0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a}, {0x1e95, 0x1e9d},
-    {0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27}, {0x1f30, 0x1f37},
-    {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67}, {0x1f70, 0x1f7d},
-    {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4},
-    {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4},
-    {0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25},
-    {0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a},
-    {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
-    {0xff41, 0xff5a}
+    {0x1c80, 0x1c88}, {0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a},
+    {0x1e95, 0x1e9d}, {0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27},
+    {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67},
+    {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7},
+    {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7},
+    {0x1ff2, 0x1ff4}, {0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b},
+    {0x2d00, 0x2d25}, {0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795},
+    {0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06},
+    {0xfb13, 0xfb17}, {0xff41, 0xff5a}
 #if TCL_UTF_MAX > 4
-    ,{0x10428, 0x1044f}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df}, {0x1d41a, 0x1d433},
-    {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b}, {0x1d4b6, 0x1d4b9},
-    {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537},
-    {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3}, {0x1d5ee, 0x1d607},
-    {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5}, {0x1d6c2, 0x1d6da},
-    {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, {0x1d736, 0x1d74e},
-    {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, {0x1d7aa, 0x1d7c2},
-    {0x1d7c4, 0x1d7c9}
+    ,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df},
+    {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b},
+    {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503},
+    {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3},
+    {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5},
+    {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b},
+    {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f},
+    {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943}
 #endif
 };
 
@@ -513,15 +519,15 @@ static const crange upperRangeTable[] = {
     {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb},
     {0x210b, 0x210d}, {0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d},
     {0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70},
-    {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ad}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
+    {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
 #if TCL_UTF_MAX > 4
-    ,{0x10400, 0x10427}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf}, {0x1d400, 0x1d419},
-    {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5},
-    {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c},
-    {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d56c, 0x1d585},
-    {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621}, {0x1d63c, 0x1d655},
-    {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734},
-    {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}
+    ,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf},
+    {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac},
+    {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
+    {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550},
+    {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621},
+    {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa},
+    {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921}
 #endif
 };
 
@@ -610,26 +616,26 @@ static const crange graphRangeTable[] = {
     {0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
     {0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
     {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x8a0, 0x8b4},
-    {0x8e3, 0x983}, {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0},
-    {0x9b6, 0x9b9}, {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3},
-    {0x9e6, 0x9fb}, {0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28},
-    {0xa2a, 0xa30}, {0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c},
-    {0xa66, 0xa75}, {0xa81, 0xa83}, {0xa85, 0xa8d}, {0xa8f, 0xa91},
-    {0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xabc, 0xac5},
-    {0xac7, 0xac9}, {0xacb, 0xacd}, {0xae0, 0xae3}, {0xae6, 0xaf1},
-    {0xb01, 0xb03}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
-    {0xb35, 0xb39}, {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63},
-    {0xb66, 0xb77}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95},
-    {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8},
-    {0xbca, 0xbcd}, {0xbe6, 0xbfa}, {0xc00, 0xc03}, {0xc05, 0xc0c},
-    {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc3d, 0xc44},
-    {0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc58, 0xc5a}, {0xc60, 0xc63},
-    {0xc66, 0xc6f}, {0xc78, 0xc7f}, {0xc81, 0xc83}, {0xc85, 0xc8c},
-    {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
-    {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3},
-    {0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
-    {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e},
-    {0xd5f, 0xd63}, {0xd66, 0xd75}, {0xd79, 0xd7f}, {0xd85, 0xd96},
+    {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
+    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
+    {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03},
+    {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
+    {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, {0xa81, 0xa83},
+    {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
+    {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
+    {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xb01, 0xb03}, {0xb05, 0xb0c},
+    {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb3c, 0xb44},
+    {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, {0xb85, 0xb8a},
+    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
+    {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, {0xbe6, 0xbfa},
+    {0xc00, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
+    {0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
+    {0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc83},
+    {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
+    {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd},
+    {0xce0, 0xce3}, {0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c},
+    {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48},
+    {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f}, {0xd85, 0xd96},
     {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4},
     {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4}, {0xe01, 0xe3a},
     {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3},
@@ -650,25 +656,25 @@ static const crange graphRangeTable[] = {
     {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89},
     {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b},
     {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49},
-    {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5},
-    {0x1dfc, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
+    {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5},
+    {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
     {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4},
     {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4},
     {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e},
     {0x2090, 0x209c}, {0x20a0, 0x20be}, {0x20d0, 0x20f0}, {0x2100, 0x218b},
-    {0x2190, 0x23fa}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
+    {0x2190, 0x23fe}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
     {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1},
     {0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
     {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
     {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
-    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e42},
+    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e44},
     {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
     {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312d},
     {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
     {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fd5}, {0xa000, 0xa48c},
-    {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ad},
+    {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae},
     {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
-    {0xa880, 0xa8c4}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
+    {0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
     {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe},
     {0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2},
     {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
@@ -687,54 +693,59 @@ static const crange graphRangeTable[] = {
 #if TCL_UTF_MAX > 4
     ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
     {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
-    {0x10137, 0x1018c}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
+    {0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
     {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a},
     {0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5},
-    {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x10500, 0x10527}, {0x10530, 0x10563},
-    {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
-    {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10857, 0x1089e}, {0x108a7, 0x108af},
-    {0x108e0, 0x108f2}, {0x108fb, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7},
-    {0x109bc, 0x109cf}, {0x109d2, 0x10a03}, {0x10a0c, 0x10a13}, {0x10a15, 0x10a17},
-    {0x10a19, 0x10a33}, {0x10a38, 0x10a3a}, {0x10a3f, 0x10a47}, {0x10a50, 0x10a58},
-    {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, {0x10aeb, 0x10af6}, {0x10b00, 0x10b35},
-    {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, {0x10b78, 0x10b91}, {0x10b99, 0x10b9c},
-    {0x10ba9, 0x10baf}, {0x10c00, 0x10c48}, {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2},
-    {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f},
-    {0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9},
-    {0x11100, 0x11134}, {0x11136, 0x11143}, {0x11150, 0x11176}, {0x11180, 0x111cd},
-    {0x111d0, 0x111df}, {0x111e1, 0x111f4}, {0x11200, 0x11211}, {0x11213, 0x1123d},
-    {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a9},
-    {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, {0x11300, 0x11303}, {0x11305, 0x1130c},
-    {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1133c, 0x11344},
-    {0x1134b, 0x1134d}, {0x1135d, 0x11363}, {0x11366, 0x1136c}, {0x11370, 0x11374},
-    {0x11480, 0x114c7}, {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd},
-    {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
+    {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb},
+    {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
+    {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
+    {0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b},
+    {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03},
+    {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a},
+    {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
+    {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
+    {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
+    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e},
+    {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1},
+    {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143},
+    {0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4},
+    {0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
+    {0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
+    {0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
+    {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
+    {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7},
+    {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644},
+    {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
     {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2},
-    {0x11ac0, 0x11af8}, {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474},
-    {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38},
-    {0x16a40, 0x16a5e}, {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5},
-    {0x16b00, 0x16b45}, {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77},
-    {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f},
-    {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
-    {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172},
-    {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356}, {0x1d360, 0x1d371},
-    {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
-    {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
-    {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
-    {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, {0x1d7ce, 0x1da8b},
-    {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6},
-    {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
-    {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
-    {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
-    {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093},
-    {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5},
-    {0x1f100, 0x1f10c}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f19a},
-    {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248}, {0x1f300, 0x1f579},
-    {0x1f57b, 0x1f5a3}, {0x1f5a5, 0x1f6d0}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f3},
-    {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847},
-    {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f910, 0x1f918},
-    {0x1f980, 0x1f984}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
-    {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
+    {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45},
+    {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6},
+    {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
+    {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
+    {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
+    {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
+    {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec},
+    {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
+    {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126},
+    {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356},
+    {0x1d360, 0x1d371}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
+    {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
+    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
+    {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
+    {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
+    {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
+    {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03},
+    {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f},
+    {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c},
+    {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9},
+    {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae},
+    {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c},
+    {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
+    {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f300, 0x1f6d2}, {0x1f6e0, 0x1f6ec},
+    {0x1f6f0, 0x1f6f6}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b},
+    {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad},
+    {0x1f910, 0x1f91e}, {0x1f920, 0x1f927}, {0x1f933, 0x1f93e}, {0x1f940, 0x1f94b},
+    {0x1f950, 0x1f95e}, {0x1f980, 0x1f991}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
+    {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
 #endif
 };
 
@@ -747,20 +758,20 @@ static const chr graphCharTable[] = {
     0xad0, 0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56,
     0xb57, 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e,
     0xb9f, 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6,
-    0xcde, 0xcf1, 0xcf2, 0xd57, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6,
-    0xe81, 0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7,
-    0xeaa, 0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773,
-    0x1940, 0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27,
-    0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc,
-    0xfffd
+    0xcde, 0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81,
+    0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa,
+    0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940,
+    0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d,
+    0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
 #if TCL_UTF_MAX > 4
     ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
     0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
-    0x11347, 0x11348, 0x11350, 0x11357, 0x118ff, 0x16a6e, 0x16a6f, 0x1b000, 0x1b001,
-    0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22,
-    0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51,
-    0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62,
-    0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f9c0
+    0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x16a6e, 0x16a6f,
+    0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
+    0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
+    0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
+    0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
+    0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f930, 0x1f9c0
 #endif
 };
 
index 3490049..3037ceb 100644 (file)
@@ -56,10 +56,10 @@ extern "C" {
 #define TCL_MAJOR_VERSION   8
 #define TCL_MINOR_VERSION   6
 #define TCL_RELEASE_LEVEL   TCL_FINAL_RELEASE
-#define TCL_RELEASE_SERIAL  5
+#define TCL_RELEASE_SERIAL  6
 
 #define TCL_VERSION        "8.6"
-#define TCL_PATCH_LEVEL            "8.6.5"
+#define TCL_PATCH_LEVEL            "8.6.6"
 \f
 /*
  *----------------------------------------------------------------------------
index 6d5676b..f56da8f 100644 (file)
@@ -3984,10 +3984,12 @@ UnstackExpiredCatches(
 
     while (catchDepth > bbPtr->catchDepth) {
        --catchDepth;
-       range = envPtr->exceptArrayPtr + catchIndices[catchDepth];
-       range->numCodeBytes = bbPtr->startOffset - range->codeOffset;
-       catches[catchDepth] = NULL;
-       catchIndices[catchDepth] = -1;
+       if (catches[catchDepth] != NULL) {
+           range = envPtr->exceptArrayPtr + catchIndices[catchDepth];
+           range->numCodeBytes = bbPtr->startOffset - range->codeOffset;
+           catches[catchDepth] = NULL;
+           catchIndices[catchDepth] = -1;
+       }
     }
 
     /*
index e5d7406..d6a460d 100644 (file)
@@ -128,7 +128,7 @@ static void         MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
                            int actual, Tcl_Obj *const *objv);
 static Tcl_NRPostProc  NRCoroutineCallerCallback;
 static Tcl_NRPostProc  NRCoroutineExitCallback;
-static int NRCommand(ClientData data[], Tcl_Interp *interp, int result);
+static Tcl_NRPostProc  NRCommand;
 
 static Tcl_ObjCmdProc  OldMathFuncProc;
 static void            OldMathFuncDeleteProc(ClientData clientData);
@@ -146,7 +146,6 @@ static int          TEOV_RunEnterTraces(Tcl_Interp *interp,
                            Command **cmdPtrPtr, Tcl_Obj *commandPtr, int objc,
                            Tcl_Obj *const objv[]);
 static Tcl_NRPostProc  RewindCoroutineCallback;
-static Tcl_NRPostProc  TailcallCleanup;
 static Tcl_NRPostProc  TEOEx_ByteCodeCallback;
 static Tcl_NRPostProc  TEOEx_ListCallback;
 static Tcl_NRPostProc  TEOV_Error;
@@ -723,9 +722,7 @@ Tcl_CreateInterp(void)
      * Initialize the ensemble error message rewriting support.
      */
 
-    iPtr->ensembleRewrite.sourceObjs = NULL;
-    iPtr->ensembleRewrite.numRemovedObjs = 0;
-    iPtr->ensembleRewrite.numInsertedObjs = 0;
+    TclResetRewriteEnsemble(interp, 1);
 
     /*
      * TIP#143: Initialise the resource limit support.
@@ -4220,7 +4217,7 @@ EvalObjvCore(
         * TCL_EVAL_INVOKE was not set: clear rewrite rules
         */
 
-       iPtr->ensembleRewrite.sourceObjs = NULL;
+       TclResetRewriteEnsemble(interp, 1);
 
        if (flags & TCL_EVAL_GLOBAL) {
            TEOV_SwitchVarFrame(interp);
@@ -8373,7 +8370,7 @@ TclNRTailcallEval(
          * a now-gone namespace: cleanup and return.
          */
 
-        TailcallCleanup(data, interp, result);
+       Tcl_DecrRefCount(listPtr);
         return result;
     }
 
@@ -8382,18 +8379,26 @@ TclNRTailcallEval(
      */
 
     TclMarkTailcall(interp);
-    TclNRAddCallback(interp, TailcallCleanup, listPtr, NULL, NULL,NULL);
+    TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL);
     iPtr->lookupNsPtr = (Namespace *) nsPtr;
     return TclNREvalObjv(interp, objc-1, objv+1, 0, NULL);
 }
 
-static int
-TailcallCleanup(
+int
+TclNRReleaseValues(
     ClientData data[],
     Tcl_Interp *interp,
     int result)
 {
-    Tcl_DecrRefCount((Tcl_Obj *) data[0]);
+    int i = 0;
+    while (i < 4) {
+       if (data[i]) {
+           Tcl_DecrRefCount((Tcl_Obj *) data[i]);
+       } else {
+           break;
+       }
+       i++;
+    }
     return result;
 }
 
index 949cb1c..c3b29e9 100644 (file)
@@ -1499,7 +1499,19 @@ GetJulianDayFromEraYearMonthDay(
      * Try an initial conversion in the Gregorian calendar.
      */
 
+#if 0 /* BUG http://core.tcl.tk/tcl/tktview?name=da340d4f32 */
     ym1o4 = ym1 / 4;
+#else
+    /*
+     * Have to make sure quotient is truncated towards 0 when negative.
+     * See above bug for details. The casts are necessary.
+     */
+    if (ym1 >= 0)
+        ym1o4 = ym1 / 4;
+    else {
+        ym1o4 = - (int) (((unsigned int) -ym1) / 4);
+    }
+#endif
     if (ym1 % 4 < 0) {
        ym1o4--;
     }
index 54e0227..88cc17d 100644 (file)
@@ -12,6 +12,9 @@
  */
 
 #include "tclInt.h"
+#ifdef _WIN32
+#   include "tclWinInt.h"
+#endif
 #include <locale.h>
 
 /*
@@ -1157,6 +1160,16 @@ FileAttrAccessTimeCmd(
     if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
        return TCL_ERROR;
     }
+#if defined(_WIN32)
+    /* We use a value of 0 to indicate the access time not available */
+    if (buf.st_atime == 0) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                             "could not get access time for file \"%s\"",
+                             TclGetString(objv[1])));
+        return TCL_ERROR;
+    }
+#endif
+
     if (objc == 3) {
        /*
         * Need separate variable for reading longs from an object on 64-bit
@@ -1229,6 +1242,15 @@ FileAttrModifyTimeCmd(
     if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
        return TCL_ERROR;
     }
+#if defined(_WIN32)
+    /* We use a value of 0 to indicate the modification time not available */
+    if (buf.st_mtime == 0) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                             "could not get modification time for file \"%s\"",
+                             TclGetString(objv[1])));
+        return TCL_ERROR;
+    }
+#endif
     if (objc == 3) {
        /*
         * Need separate variable for reading longs from an object on 64-bit
@@ -1574,28 +1596,25 @@ FileAttrIsOwnedCmd(
     int objc,
     Tcl_Obj *const objv[])
 {
+#ifdef __CYGWIN__
+#define geteuid() (short)(geteuid)() 
+#endif
+#if !defined(_WIN32)
     Tcl_StatBuf buf;
+#endif
     int value = 0;
 
     if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "name");
        return TCL_ERROR;
     }
-    if (GetStatBuf(NULL, objv[1], Tcl_FSStat, &buf) == TCL_OK) {
-       /*
-        * For Windows, there are no user ids associated with a file, so we
-        * always return 1.
-        *
-        * TODO: use GetSecurityInfo to get the real owner of the file and
-        * test for equivalence to the current user.
-        */
-
-#if defined(_WIN32) || defined(__CYGWIN__)
-       value = 1;
+#if defined(_WIN32)
+    value = TclWinFileOwned(objv[1]);
 #else
+    if (GetStatBuf(NULL, objv[1], Tcl_FSStat, &buf) == TCL_OK) {
        value = (geteuid() == buf.st_uid);
-#endif
     }
+#endif
     Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
     return TCL_OK;
 }
index 739dca9..0a1b4fe 100644 (file)
@@ -105,8 +105,7 @@ typedef struct SortInfo {
  */
 
 static int             DictionaryCompare(const char *left, const char *right);
-static int             IfConditionCallback(ClientData data[],
-                           Tcl_Interp *interp, int result);
+static Tcl_NRPostProc  IfConditionCallback;
 static int             InfoArgsCmd(ClientData dummy, Tcl_Interp *interp,
                            int objc, Tcl_Obj *const objv[]);
 static int             InfoBodyCmd(ClientData dummy, Tcl_Interp *interp,
@@ -1203,7 +1202,7 @@ InfoFrameCmd(
     levelError:
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                "bad level \"%s\"", TclGetString(objv[1])));
-       Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_FRAME",
+       Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
                TclGetString(objv[1]), NULL);
        code = TCL_ERROR;
        goto done;
@@ -1638,7 +1637,7 @@ InfoLevelCmd(
   levelError:
     Tcl_SetObjResult(interp, Tcl_ObjPrintf(
            "bad level \"%s\"", TclGetString(objv[1])));
-    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
            TclGetString(objv[1]), NULL);
     return TCL_ERROR;
 }
@@ -2755,7 +2754,7 @@ Tcl_LreplaceObjCmd(
      * (to allow for replacing the last elem).
      */
 
-    if ((first >= listLen) && (listLen > 0)) {
+    if ((first > listLen) && (listLen > 0)) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                "list doesn't contain element %s", TclGetString(objv[2])));
        Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX",
index 13f9e7d..885a0bc 100644 (file)
 
 static inline Tcl_Obj *        During(Tcl_Interp *interp, int resultCode,
                            Tcl_Obj *oldOptions, Tcl_Obj *errorInfo);
-static int             SwitchPostProc(ClientData data[], Tcl_Interp *interp,
-                           int result);
-static int             TryPostBody(ClientData data[], Tcl_Interp *interp,
-                           int result);
-static int             TryPostFinal(ClientData data[], Tcl_Interp *interp,
-                           int result);
-static int             TryPostHandler(ClientData data[], Tcl_Interp *interp,
-                           int result);
+static Tcl_NRPostProc  SwitchPostProc;
+static Tcl_NRPostProc  TryPostBody;
+static Tcl_NRPostProc  TryPostFinal;
+static Tcl_NRPostProc  TryPostHandler;
 static int             UniCharIsAscii(int character);
 static int             UniCharIsHexDigit(int character);
 
index e674fb0..ffe39ba 100644 (file)
@@ -1488,8 +1488,27 @@ TclCompileLreplaceCmd(
        return TCL_ERROR;
     }
 
-    if(idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) {
-       idx2 = idx1-1;
+    /*
+     * idx1, idx2 are now in canonical form:
+     *
+     *  - integer:     [0,len+1]
+     *  - end index:    INDEX_END
+     *  - -ive offset:  INDEX_END-[len-1,0]
+     *  - +ive offset:  INDEX_END+1
+     */
+
+    /*
+     * Compilation fails when one index is end-based but the other isn't.
+     * Fixing this will require more bytecodes, but this is a workaround for
+     * now. [Bug 47ac84309b]
+     */
+
+    if ((idx1 <= INDEX_END) != (idx2 <= INDEX_END)) {
+       return TCL_ERROR;
+    }
+
+    if (idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) {
+       idx2 = idx1 - 1;
     }
 
     /*
@@ -1511,6 +1530,9 @@ TclCompileLreplaceCmd(
            idx1 = 0;
            goto dropEnd;
        } else {
+           if (idx2 < idx1) {
+               idx2 = idx1 - 1;
+           }
            if (idx1 > 0) {
                tmpObj = Tcl_NewIntObj(idx1);
                Tcl_IncrRefCount(tmpObj);
@@ -1538,9 +1560,7 @@ TclCompileLreplaceCmd(
        idx1 = 0;
        goto replaceTail;
     } else {
-       if (idx1 > 0 && idx2 > 0 && idx2 < idx1) {
-           idx2 = idx1 - 1;
-       } else if (idx1 < 0 && idx2 < 0 && idx2 < idx1) {
+       if (idx2 < idx1) {
            idx2 = idx1 - 1;
        }
        if (idx1 > 0) {
@@ -1556,7 +1576,7 @@ TclCompileLreplaceCmd(
      * operate on.
      */
 
-  dropAll:
+  dropAll:                     /* This just ensures the arg is a list. */
     TclEmitOpcode(             INST_LIST_LENGTH,               envPtr);
     TclEmitOpcode(             INST_POP,                       envPtr);
     PushStringLiteral(envPtr,  "");
@@ -1569,12 +1589,21 @@ TclCompileLreplaceCmd(
 
   dropRange:
     if (tmpObj != NULL) {
+       /*
+        * Emit bytecode to check the list length.
+        */
+
        TclEmitOpcode(          INST_DUP,                       envPtr);
        TclEmitOpcode(          INST_LIST_LENGTH,               envPtr);
        TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL),     envPtr);
-       TclEmitOpcode(          INST_GT,                        envPtr);
+       TclEmitOpcode(          INST_GE,                        envPtr);
        offset = CurrentOffset(envPtr);
        TclEmitInstInt1(        INST_JUMP_TRUE1, 0,             envPtr);
+
+       /*
+        * Emit an error if we've been given an empty list.
+        */
+
        TclEmitOpcode(          INST_DUP,                       envPtr);
        TclEmitOpcode(          INST_LIST_LENGTH,               envPtr);
        offset2 = CurrentOffset(envPtr);
@@ -1625,16 +1654,30 @@ TclCompileLreplaceCmd(
 
   replaceRange:
     if (tmpObj != NULL) {
+       /*
+        * Emit bytecode to check the list length.
+        */
+
        TclEmitOpcode(          INST_DUP,                       envPtr);
        TclEmitOpcode(          INST_LIST_LENGTH,               envPtr);
+
+       /*
+        * Check the list length vs idx1.
+        */
+
        TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL),     envPtr);
-       TclEmitOpcode(          INST_GT,                        envPtr);
+       TclEmitOpcode(          INST_GE,                        envPtr);
        offset = CurrentOffset(envPtr);
        TclEmitInstInt1(        INST_JUMP_TRUE1, 0,             envPtr);
+
+       /*
+        * Emit an error if we've been given an empty list.
+        */
+
        TclEmitOpcode(          INST_DUP,                       envPtr);
        TclEmitOpcode(          INST_LIST_LENGTH,               envPtr);
        offset2 = CurrentOffset(envPtr);
-       TclEmitInstInt1(        INST_JUMP_TRUE1, 0,             envPtr);
+       TclEmitInstInt1(        INST_JUMP_FALSE1, 0,            envPtr);
        TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
                "list doesn't contain element %d", idx1), NULL), envPtr);
        CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
@@ -2966,10 +3009,12 @@ IndexTailVarIfKnown(
     } else {
        full = 0;
        lastTokenPtr = varTokenPtr + n;
-       if (!TclWordKnownAtCompileTime(lastTokenPtr, tailPtr)) {
+
+       if (lastTokenPtr->type != TCL_TOKEN_TEXT) {
            Tcl_DecrRefCount(tailPtr);
            return -1;
        }
+       Tcl_SetStringObj(tailPtr, lastTokenPtr->start, lastTokenPtr->size);
     }
 
     tailName = TclGetStringFromObj(tailPtr, &len);
index ef9340e..101edbd 100644 (file)
@@ -2028,7 +2028,7 @@ IssueSwitchChainedTests(
     int foundDefault;          /* Flag to indicate whether a "default" clause
                                 * is present. */
     JumpFixup *fixupArray;     /* Array of forward-jump fixup records. */
-    int *fixupTargetArray;     /* Array of places for fixups to point at. */
+    unsigned int *fixupTargetArray; /* Array of places for fixups to point at. */
     int fixupCount;            /* Number of places to fix up. */
     int contFixIndex;          /* Where the first of the jumps due to a group
                                 * of continuation bodies starts, or -1 if
index 50edbec..4390282 100644 (file)
@@ -564,13 +564,13 @@ ParseExpr(
 {
     OpNode *nodes = NULL;      /* Pointer to the OpNode storage array where
                                 * we build the parse tree. */
-    int nodesAvailable = 64;   /* Initial size of the storage array. This
+    unsigned int nodesAvailable = 64; /* Initial size of the storage array. This
                                 * value establishes a minimum tree memory
                                 * cost of only about 1 kibyte, and is large
                                 * enough for most expressions to parse with
                                 * no need for array growth and
                                 * reallocation. */
-    int nodesUsed = 0;         /* Number of OpNodes filled. */
+    unsigned int nodesUsed = 0;        /* Number of OpNodes filled. */
     int scanned = 0;           /* Capture number of byte scanned by parsing
                                 * routines. */
     int lastParsed;            /* Stores info about what the lexeme parsed
@@ -662,7 +662,7 @@ ParseExpr(
         */
 
        if (nodesUsed >= nodesAvailable) {
-           int size = nodesUsed * 2;
+           unsigned int size = nodesUsed * 2;
            OpNode *newPtr = NULL;
 
            do {
index 4c259ab..c0203dd 100644 (file)
@@ -3239,8 +3239,10 @@ EnterCmdWordData(
        TclAdvanceLines(&wordLine, last, tokenPtr->start);
        TclAdvanceContinuations(&wordLine, &wordNext,
                tokenPtr->start - envPtr->source);
+       /* See Ticket 4b61afd660 */
        wwlines[wordIdx] =
-               (TclWordKnownAtCompileTime(tokenPtr, NULL) ? wordLine : -1);
+               ((wordIdx == 0) || TclWordKnownAtCompileTime(tokenPtr, NULL))
+               ? wordLine : -1;
        ePtr->line[wordIdx] = wordLine;
        ePtr->next[wordIdx] = wordNext;
        last = tokenPtr->start;
@@ -3360,26 +3362,25 @@ TclGetInnermostExceptionRange(
     int returnCode,
     ExceptionAux **auxPtrPtr)
 {
-    int exnIdx = -1, i;
+    int i = envPtr->exceptArrayNext;
+    ExceptionRange *rangePtr = envPtr->exceptArrayPtr + i;
 
-    for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
-       ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
+    while (i > 0) {
+       rangePtr--; i--;
 
        if (CurrentOffset(envPtr) >= rangePtr->codeOffset &&
                (rangePtr->numCodeBytes == -1 || CurrentOffset(envPtr) <
                        rangePtr->codeOffset+rangePtr->numCodeBytes) &&
                (returnCode != TCL_CONTINUE ||
                        envPtr->exceptAuxArrayPtr[i].supportsContinue)) {
-           exnIdx = i;
+
+           if (auxPtrPtr) {
+               *auxPtrPtr = envPtr->exceptAuxArrayPtr + i;
+           }
+           return rangePtr;
        }
     }
-    if (exnIdx == -1) {
-       return NULL;
-    }
-    if (auxPtrPtr) {
-       *auxPtrPtr = &envPtr->exceptAuxArrayPtr[exnIdx];
-    }
-    return &envPtr->exceptArrayPtr[exnIdx];
+    return NULL;
 }
 \f
 /*
index b5bfab1..d5bc86b 100644 (file)
@@ -135,7 +135,7 @@ typedef struct ExceptionAux {
     int numBreakTargets;       /* The number of [break]s that want to be
                                 * targeted to the place where this loop
                                 * exception will be bound to. */
-    int *breakTargets;         /* The offsets of the INST_JUMP4 instructions
+    unsigned int *breakTargets;        /* The offsets of the INST_JUMP4 instructions
                                 * issued by the [break]s that we must
                                 * update. Note that resizing a jump (via
                                 * TclFixupForwardJump) can cause the contents
@@ -145,7 +145,7 @@ typedef struct ExceptionAux {
     int numContinueTargets;    /* The number of [continue]s that want to be
                                 * targeted to the place where this loop
                                 * exception will be bound to. */
-    int *continueTargets;      /* The offsets of the INST_JUMP4 instructions
+    unsigned int *continueTargets; /* The offsets of the INST_JUMP4 instructions
                                 * issued by the [continue]s that we must
                                 * update. Note that resizing a jump (via
                                 * TclFixupForwardJump) can cause the contents
@@ -928,7 +928,7 @@ typedef enum {
 
 typedef struct JumpFixup {
     TclJumpType jumpType;      /* Indicates the kind of jump. */
-    int codeOffset;            /* Offset of the first byte of the one-byte
+    unsigned int codeOffset;   /* Offset of the first byte of the one-byte
                                 * forward jump's code. */
     int cmdIndex;              /* Index of the first command after the one
                                 * for which the jump was emitted. Used to
index 6222a8a..e4dd000 100644 (file)
@@ -359,14 +359,8 @@ typedef short int yytype_int16;
 #ifndef YYSIZE_T
 # ifdef __SIZE_TYPE__
 #  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T size_t
 # endif
 #endif
 
index c8474e6..428173d 100644 (file)
@@ -70,18 +70,12 @@ static inline void  DeleteChainTable(struct Dict *dict);
 static inline Tcl_HashEntry *CreateChainEntry(struct Dict *dict,
                            Tcl_Obj *keyPtr, int *newPtr);
 static inline int      DeleteChainEntry(struct Dict *dict, Tcl_Obj *keyPtr);
-static int             FinalizeDictUpdate(ClientData data[],
-                           Tcl_Interp *interp, int result);
-static int             FinalizeDictWith(ClientData data[],
-                           Tcl_Interp *interp, int result);
-static int             DictForNRCmd(ClientData dummy, Tcl_Interp *interp,
-                           int objc, Tcl_Obj *const *objv);
-static int             DictMapNRCmd(ClientData dummy, Tcl_Interp *interp,
-                           int objc, Tcl_Obj *const *objv);
-static int             DictForLoopCallback(ClientData data[],
-                           Tcl_Interp *interp, int result);
-static int             DictMapLoopCallback(ClientData data[],
-                           Tcl_Interp *interp, int result);
+static Tcl_NRPostProc  FinalizeDictUpdate;
+static Tcl_NRPostProc  FinalizeDictWith;
+static Tcl_ObjCmdProc  DictForNRCmd;
+static Tcl_ObjCmdProc  DictMapNRCmd;
+static Tcl_NRPostProc  DictForLoopCallback;
+static Tcl_NRPostProc  DictMapLoopCallback;
 
 /*
  * Table of dict subcommand names and implementations.
index c85fe13..1d616fb 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1996-1998 Sun Microsystems, Inc.
  * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
- * Copyright (c) 2013 Donal K. Fellows.
+ * Copyright (c) 2013-2016 Donal K. Fellows.
  *
  * See the file "license.terms" for information on usage and redistribution of
  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -1279,9 +1279,11 @@ Tcl_DisassembleObjCmd(
     Tcl_Obj *const objv[])     /* Argument objects. */
 {
     static const char *const types[] = {
+       "constructor", "destructor",
        "lambda", "method", "objmethod", "proc", "script", NULL
     };
     enum Types {
+       DISAS_CLASS_CONSTRUCTOR, DISAS_CLASS_DESTRUCTOR,
        DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC,
        DISAS_SCRIPT
     };
@@ -1290,6 +1292,7 @@ Tcl_DisassembleObjCmd(
     Proc *procPtr = NULL;
     Tcl_HashEntry *hPtr;
     Object *oPtr;
+    Method *methodPtr;
 
     if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "type ...");
@@ -1384,6 +1387,136 @@ Tcl_DisassembleObjCmd(
        codeObjPtr = objv[2];
        break;
 
+    case DISAS_CLASS_CONSTRUCTOR:
+       if (objc != 3) {
+           Tcl_WrongNumArgs(interp, 2, objv, "className");
+           return TCL_ERROR;
+       }
+
+       /*
+        * Look up the body of a constructor.
+        */
+
+       oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
+       if (oPtr == NULL) {
+           return TCL_ERROR;
+       }
+       if (oPtr->classPtr == NULL) {
+           Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                   "\"%s\" is not a class", TclGetString(objv[2])));
+           Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+                   TclGetString(objv[2]), NULL);
+           return TCL_ERROR;
+       }
+
+       methodPtr = oPtr->classPtr->constructorPtr;
+       if (methodPtr == NULL) {
+           Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                   "\"%s\" has no defined constructor",
+                   TclGetString(objv[2])));
+           Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+                   "CONSRUCTOR", NULL);
+           return TCL_ERROR;
+       }
+       procPtr = TclOOGetProcFromMethod(methodPtr);
+       if (procPtr == NULL) {
+           Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                   "body not available for this kind of constructor", -1));
+           Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+                   "METHODTYPE", NULL);
+           return TCL_ERROR;
+       }
+
+       /*
+        * Compile if necessary.
+        */
+
+       if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
+           Command cmd;
+
+           /*
+            * Yes, this is ugly, but we need to pass the namespace in to the
+            * compiler in two places.
+            */
+
+           cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
+           procPtr->cmdPtr = &cmd;
+           result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
+                   (Namespace *) oPtr->namespacePtr, "body of constructor",
+                   TclGetString(objv[2]));
+           procPtr->cmdPtr = NULL;
+           if (result != TCL_OK) {
+               return result;
+           }
+       }
+       codeObjPtr = procPtr->bodyPtr;
+       break;
+
+    case DISAS_CLASS_DESTRUCTOR:
+       if (objc != 3) {
+           Tcl_WrongNumArgs(interp, 2, objv, "className");
+           return TCL_ERROR;
+       }
+
+       /*
+        * Look up the body of a destructor.
+        */
+
+       oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
+       if (oPtr == NULL) {
+           return TCL_ERROR;
+       }
+       if (oPtr->classPtr == NULL) {
+           Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                   "\"%s\" is not a class", TclGetString(objv[2])));
+           Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+                   TclGetString(objv[2]), NULL);
+           return TCL_ERROR;
+       }
+
+       methodPtr = oPtr->classPtr->destructorPtr;
+       if (methodPtr == NULL) {
+           Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                   "\"%s\" has no defined destructor",
+                   TclGetString(objv[2])));
+           Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+                   "DESRUCTOR", NULL);
+           return TCL_ERROR;
+       }
+       procPtr = TclOOGetProcFromMethod(methodPtr);
+       if (procPtr == NULL) {
+           Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                   "body not available for this kind of destructor", -1));
+           Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+                   "METHODTYPE", NULL);
+           return TCL_ERROR;
+       }
+
+       /*
+        * Compile if necessary.
+        */
+
+       if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
+           Command cmd;
+
+           /*
+            * Yes, this is ugly, but we need to pass the namespace in to the
+            * compiler in two places.
+            */
+
+           cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
+           procPtr->cmdPtr = &cmd;
+           result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
+                   (Namespace *) oPtr->namespacePtr, "body of destructor",
+                   TclGetString(objv[2]));
+           procPtr->cmdPtr = NULL;
+           if (result != TCL_OK) {
+               return result;
+           }
+       }
+       codeObjPtr = procPtr->bodyPtr;
+       break;
+
     case DISAS_CLASS_METHOD:
        if (objc != 4) {
            Tcl_WrongNumArgs(interp, 2, objv, "className methodName");
index 8f7d1a2..8e5e410 100644 (file)
@@ -30,11 +30,10 @@ static int          NsEnsembleStringOrder(const void *strPtr1,
                            const void *strPtr2);
 static void            DeleteEnsembleConfig(ClientData clientData);
 static void            MakeCachedEnsembleCommand(Tcl_Obj *objPtr,
-                           EnsembleConfig *ensemblePtr,
-                           const char *subcmdName, Tcl_Obj *prefixObjPtr);
+                           EnsembleConfig *ensemblePtr, Tcl_HashEntry *hPtr,
+                           Tcl_Obj *fix);
 static void            FreeEnsembleCmdRep(Tcl_Obj *objPtr);
 static void            DupEnsembleCmdRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
-static void            StringOfEnsembleCmdRep(Tcl_Obj *objPtr);
 static void            CompileToInvokedCommand(Tcl_Interp *interp,
                            Tcl_Parse *parsePtr, Tcl_Obj *replacements,
                            Command *cmdPtr, CompileEnv *envPtr);
@@ -42,6 +41,8 @@ static int            CompileBasicNArgCommand(Tcl_Interp *interp,
                            Tcl_Parse *parsePtr, Command *cmdPtr,
                            CompileEnv *envPtr);
 
+static Tcl_NRPostProc  FreeER;
+
 /*
  * The lists of subcommands and options for the [namespace ensemble] command.
  */
@@ -77,14 +78,30 @@ enum EnsConfigOpts {
  * that implements it.
  */
 
-const Tcl_ObjType tclEnsembleCmdType = {
+static const Tcl_ObjType ensembleCmdType = {
     "ensembleCommand",         /* the type's name */
     FreeEnsembleCmdRep,                /* freeIntRepProc */
     DupEnsembleCmdRep,         /* dupIntRepProc */
-    StringOfEnsembleCmdRep,    /* updateStringProc */
+    NULL,                      /* updateStringProc */
     NULL                       /* setFromAnyProc */
 };
 
+/*
+ * The internal rep for caching ensemble subcommand lookups and
+ * spell corrections.
+ */
+
+typedef struct {
+    int epoch;                  /* Used to confirm when the data in this
+                                 * really structure matches up with the
+                                 * ensemble. */
+    Command *token;             /* Reference to the command for which this
+                                 * structure is a cache of the resolution. */
+    Tcl_Obj *fix;               /* Corrected spelling, if needed. */
+    Tcl_HashEntry *hPtr;        /* Direct link to entry in the subcommand
+                                 * hash table. */
+} EnsembleCmdRep;
+
 \f
 static inline Tcl_Obj *
 NewNsObj(
@@ -1643,6 +1660,8 @@ NsEnsembleImplementationCmdNR(
                                 * names. */
     int reparseCount = 0;      /* Number of reparses. */
     Tcl_Obj *errorObj;         /* Used for building error messages. */
+    Tcl_Obj *subObj;
+    int subIdx;
 
     /*
      * Must recheck objc, since numParameters might have changed. Cf. test
@@ -1650,24 +1669,18 @@ NsEnsembleImplementationCmdNR(
      */
 
   restartEnsembleParse:
-    if (objc < 2 + ensemblePtr->numParameters) {
+    subIdx = 1 + ensemblePtr->numParameters;
+    if (objc < subIdx + 1) {
        /*
         * We don't have a subcommand argument. Make error message.
         */
 
        Tcl_DString buf;        /* Message being built */
-       Tcl_Obj **elemPtrs;     /* Parameter names */
-       int len;                /* Number of parameters to append */
 
        Tcl_DStringInit(&buf);
-       if (ensemblePtr->parameterList == NULL) {
-           len = 0;
-       } else if (TclListObjGetElements(NULL, ensemblePtr->parameterList,
-               &len, &elemPtrs) != TCL_OK) {
-           Tcl_Panic("List of ensemble parameters is not a list");
-       }
-       for (; len>0; len--,elemPtrs++) {
-           TclDStringAppendObj(&buf, *elemPtrs);
+       if (ensemblePtr->parameterList) {
+           Tcl_DStringAppend(&buf,
+                   TclGetString(ensemblePtr->parameterList), -1);
            TclDStringAppendLiteral(&buf, " ");
        }
        TclDStringAppendLiteral(&buf, "subcommand ?arg ...?");
@@ -1695,6 +1708,8 @@ NsEnsembleImplementationCmdNR(
      * up in there and go straight to dispatch.
      */
 
+    subObj = objv[subIdx];
+
     if (ensemblePtr->epoch == ensemblePtr->nsPtr->exportLookupEpoch) {
        /*
         * Table of subcommands is still valid; therefore there might be a
@@ -1703,15 +1718,16 @@ NsEnsembleImplementationCmdNR(
         * part where we do the invocation of the subcommand.
         */
 
-       if (objv[1+ensemblePtr->numParameters]->typePtr==&tclEnsembleCmdType){
-           EnsembleCmdRep *ensembleCmd = objv[1+ensemblePtr->numParameters]
-                   ->internalRep.twoPtrValue.ptr1;
+       if (subObj->typePtr==&ensembleCmdType){
+           EnsembleCmdRep *ensembleCmd = subObj->internalRep.twoPtrValue.ptr1;
 
-           if (ensembleCmd->nsPtr == ensemblePtr->nsPtr &&
-                   ensembleCmd->epoch == ensemblePtr->epoch &&
-                   ensembleCmd->token == ensemblePtr->token) {
-               prefixObj = ensembleCmd->realPrefixObj;
+           if (ensembleCmd->epoch == ensemblePtr->epoch &&
+                   ensembleCmd->token == (Command *)ensemblePtr->token) {
+               prefixObj = Tcl_GetHashValue(ensembleCmd->hPtr);
                Tcl_IncrRefCount(prefixObj);
+               if (ensembleCmd->fix) {
+                   TclSpellFix(interp, objv, objc, subIdx, subObj, ensembleCmd->fix);
+               }
                goto runResultingSubcommand;
            }
        }
@@ -1726,18 +1742,14 @@ NsEnsembleImplementationCmdNR(
      */
 
     hPtr = Tcl_FindHashEntry(&ensemblePtr->subcommandTable,
-           TclGetString(objv[1 + ensemblePtr->numParameters]));
+           TclGetString(subObj));
     if (hPtr != NULL) {
-       char *fullName = Tcl_GetHashKey(&ensemblePtr->subcommandTable, hPtr);
-
-       prefixObj = Tcl_GetHashValue(hPtr);
 
        /*
         * Cache for later in the subcommand object.
         */
 
-       MakeCachedEnsembleCommand(objv[1 + ensemblePtr->numParameters],
-               ensemblePtr, fullName, prefixObj);
+       MakeCachedEnsembleCommand(subObj, ensemblePtr, hPtr, NULL);
     } else if (!(ensemblePtr->flags & TCL_ENSEMBLE_PREFIX)) {
        /*
         * Could not map, no prefixing, go to unknown/error handling.
@@ -1757,9 +1769,9 @@ NsEnsembleImplementationCmdNR(
        char *fullName = NULL;  /* Full name of the subcommand. */
        int stringLength, i;
        int tableLength = ensemblePtr->subcommandTable.numEntries;
+       Tcl_Obj *fix;
 
-       subcmdName = TclGetString(objv[1 + ensemblePtr->numParameters]);
-       stringLength = objv[1 + ensemblePtr->numParameters]->length;
+       subcmdName = Tcl_GetStringFromObj(subObj, &stringLength);
        for (i=0 ; i<tableLength ; i++) {
            register int cmp = strncmp(subcmdName,
                    ensemblePtr->subcommandArrayPtr[i],
@@ -1799,16 +1811,22 @@ NsEnsembleImplementationCmdNR(
            Tcl_Panic("full name %s not found in supposedly synchronized hash",
                    fullName);
        }
-       prefixObj = Tcl_GetHashValue(hPtr);
+
+       /*
+        * Record the spelling correction for usage message.
+        */
+
+       fix = Tcl_NewStringObj(fullName, -1);
 
        /*
         * Cache for later in the subcommand object.
         */
 
-       MakeCachedEnsembleCommand(objv[1 + ensemblePtr->numParameters],
-               ensemblePtr, fullName, prefixObj);
+       MakeCachedEnsembleCommand(subObj, ensemblePtr, hPtr, fix);
+       TclSpellFix(interp, objv, objc, subIdx, subObj, fix);
     }
 
+    prefixObj = Tcl_GetHashValue(hPtr);
     Tcl_IncrRefCount(prefixObj);
   runResultingSubcommand:
 
@@ -1827,47 +1845,26 @@ NsEnsembleImplementationCmdNR(
      */
 
     {
-       Tcl_Obj **prefixObjv;   /* The list of objects to substitute in as the
-                                * target command prefix. */
        Tcl_Obj *copyPtr;       /* The actual list of words to dispatch to.
                                 * Will be freed by the dispatch engine. */
-       int prefixObjc, copyObjc;
-       Interp *iPtr = (Interp *) interp;
+       Tcl_Obj **copyObjv;
+       int copyObjc, prefixObjc;
 
-       /*
-        * Get the prefix that we're rewriting to. To do this we need to
-        * ensure that the internal representation of the list does not change
-        * so that we can safely keep the internal representations of the
-        * elements in the list.
-        *
-        * TODO: Use conventional list operations to make this code sane!
-        */
+       Tcl_ListObjLength(NULL, prefixObj, &prefixObjc);
 
-       TclListObjGetElements(NULL, prefixObj, &prefixObjc, &prefixObjv);
-
-       copyObjc = objc - 2 + prefixObjc;
-       copyPtr = Tcl_NewListObj(copyObjc, NULL);
-       if (copyObjc > 0) {
-           register Tcl_Obj **copyObjv;
-                               /* Space used to construct the list of
-                                * arguments to pass to the command that
-                                * implements the ensemble subcommand. */
-           register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1;
-           register int i;
-
-           listRepPtr->elemCount = copyObjc;
-           copyObjv = &listRepPtr->elements;
-           memcpy(copyObjv, prefixObjv, sizeof(Tcl_Obj *) * prefixObjc);
-           memcpy(copyObjv+prefixObjc, objv+1,
-                   sizeof(Tcl_Obj *) * ensemblePtr->numParameters);
-           memcpy(copyObjv+prefixObjc+ensemblePtr->numParameters,
-                   objv+ensemblePtr->numParameters+2,
-                   sizeof(Tcl_Obj *) * (objc-ensemblePtr->numParameters-2));
-
-           for (i=0; i < copyObjc; i++) {
-               Tcl_IncrRefCount(copyObjv[i]);
-           }
-       }
+       if (objc == 2) {
+           copyPtr = TclListObjCopy(NULL, prefixObj);
+       } else {
+           copyPtr = Tcl_NewListObj(objc - 2 + prefixObjc, NULL);
+           Tcl_ListObjAppendList(NULL, copyPtr, prefixObj);
+           Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
+                   ensemblePtr->numParameters, objv + 1);
+           Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
+                   objc - 2 - ensemblePtr->numParameters,
+                   objv + 2 + ensemblePtr->numParameters);
+       }
+       Tcl_IncrRefCount(copyPtr);
+       TclNRAddCallback(interp, TclNRReleaseValues, copyPtr, NULL, NULL, NULL);
        TclDecrRefCount(prefixObj);
 
        /*
@@ -1876,25 +1873,10 @@ NsEnsembleImplementationCmdNR(
         * count both as inserted and removed arguments.
         */
 
-       if (iPtr->ensembleRewrite.sourceObjs == NULL) {
-           iPtr->ensembleRewrite.sourceObjs = objv;
-           iPtr->ensembleRewrite.numRemovedObjs =
-                   2 + ensemblePtr->numParameters;
-           iPtr->ensembleRewrite.numInsertedObjs =
-                   prefixObjc + ensemblePtr->numParameters;
+       if (TclInitRewriteEnsemble(interp, 2 + ensemblePtr->numParameters,
+               prefixObjc + ensemblePtr->numParameters, objv)) {
            TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL,
                    NULL);
-       } else {
-           register int ni = 2 + ensemblePtr->numParameters
-                   - iPtr->ensembleRewrite.numInsertedObjs;
-                               /* Position in objv of new front of insertion
-                                * relative to old one. */
-           if (ni > 0) {
-               iPtr->ensembleRewrite.numRemovedObjs += ni;
-               iPtr->ensembleRewrite.numInsertedObjs += prefixObjc-1;
-           } else {
-               iPtr->ensembleRewrite.numInsertedObjs += prefixObjc-2;
-           }
        }
 
        /*
@@ -1902,7 +1884,8 @@ NsEnsembleImplementationCmdNR(
         */
 
        TclSkipTailcall(interp);
-       return TclNREvalObjEx(interp, copyPtr, TCL_EVAL_INVOKE, NULL,INT_MIN);
+       Tcl_ListObjGetElements(NULL, copyPtr, &copyObjc, &copyObjv);
+       return TclNREvalObjv(interp, copyObjc, copyObjv, TCL_EVAL_INVOKE, NULL);
     }
 
   unknownOrAmbiguousSubcommand:
@@ -1934,20 +1917,17 @@ NsEnsembleImplementationCmdNR(
 
     Tcl_ResetResult(interp);
     Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
-           TclGetString(objv[1+ensemblePtr->numParameters]), NULL);
+           TclGetString(subObj), NULL);
     if (ensemblePtr->subcommandTable.numEntries == 0) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                "unknown subcommand \"%s\": namespace %s does not"
-               " export any commands",
-               TclGetString(objv[1+ensemblePtr->numParameters]),
+               " export any commands", TclGetString(subObj),
                ensemblePtr->nsPtr->fullName));
-       Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
-               TclGetString(objv[1+ensemblePtr->numParameters]), NULL);
        return TCL_ERROR;
     }
     errorObj = Tcl_ObjPrintf("unknown%s subcommand \"%s\": must be ",
            (ensemblePtr->flags & TCL_ENSEMBLE_PREFIX ? " or ambiguous" : ""),
-           TclGetString(objv[1+ensemblePtr->numParameters]));
+           TclGetString(subObj));
     if (ensemblePtr->subcommandTable.numEntries == 1) {
        Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[0], -1);
     } else {
@@ -2013,7 +1993,7 @@ TclInitRewriteEnsemble(
 
        if (numIns < numRemoved) {
            iPtr->ensembleRewrite.numRemovedObjs += numRemoved - numIns;
-           iPtr->ensembleRewrite.numInsertedObjs += numInserted - 1;
+           iPtr->ensembleRewrite.numInsertedObjs = numInserted;
        } else {
            iPtr->ensembleRewrite.numInsertedObjs += numInserted - numRemoved;
        }
@@ -2054,6 +2034,149 @@ TclResetRewriteEnsemble(
 }
 \f
 /*
+ *----------------------------------------------------------------------
+ *
+ * TclSpellFix --
+ *
+ *     Record a spelling correction that needs making in the
+ *     generation of the WrongNumArgs usage message.
+ *
+ * Results:
+ *     None.
+ *
+ * Side effects:
+ *     Can create an alternative ensemble rewrite structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FreeER(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj **tmp = (Tcl_Obj **)data[0];
+
+    ckfree(tmp[2]);
+    ckfree(tmp);
+    return result;
+}
+
+void
+TclSpellFix(
+    Tcl_Interp *interp,
+    Tcl_Obj *const *objv,
+    int objc,
+    int badIdx,
+    Tcl_Obj *bad,
+    Tcl_Obj *fix)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *const *search;
+    Tcl_Obj **store;
+    int idx;
+    int size;
+
+    if (iPtr->ensembleRewrite.sourceObjs == NULL) {
+       iPtr->ensembleRewrite.sourceObjs = objv;
+       iPtr->ensembleRewrite.numRemovedObjs = 0;
+       iPtr->ensembleRewrite.numInsertedObjs = 0;
+    }
+
+    /* Compute the valid length of the ensemble root */
+
+    size = iPtr->ensembleRewrite.numRemovedObjs + objc
+               - iPtr->ensembleRewrite.numInsertedObjs;
+
+    search = iPtr->ensembleRewrite.sourceObjs;
+    if (search[0] == NULL) {
+       /* Awful casting abuse here */
+       search = (Tcl_Obj *const *) search[1];
+    }
+
+    if (badIdx < iPtr->ensembleRewrite.numInsertedObjs) {
+       /*
+        * Misspelled value was inserted. We cannot directly jump
+        * to the bad value, but have to search.
+        */
+       idx = 1;
+       while (idx < size) {
+           if (search[idx] == bad) {
+               break;
+           }
+           idx++;
+       }
+       if (idx == size) {
+           return;
+       }
+    } else {
+       /* Jump to the misspelled value. */
+       idx = iPtr->ensembleRewrite.numRemovedObjs + badIdx
+               - iPtr->ensembleRewrite.numInsertedObjs;
+
+       /* Verify */
+       if (search[idx] != bad) {
+           Tcl_Panic("SpellFix: programming error");
+       }
+    }
+
+    search = iPtr->ensembleRewrite.sourceObjs;
+    if (search[0] == NULL) {
+       store = (Tcl_Obj **)search[2];
+    }  else {
+       Tcl_Obj **tmp = ckalloc(3 * sizeof(Tcl_Obj *));
+       tmp[0] = NULL;
+       tmp[1] = (Tcl_Obj *)iPtr->ensembleRewrite.sourceObjs;
+       tmp[2] = (Tcl_Obj *)ckalloc(size * sizeof(Tcl_Obj *));
+       memcpy(tmp[2], tmp[1], size*sizeof(Tcl_Obj *));
+
+       iPtr->ensembleRewrite.sourceObjs = (Tcl_Obj *const *) tmp;
+       TclNRAddCallback(interp, FreeER, tmp, NULL, NULL, NULL);
+       store = (Tcl_Obj **)tmp[2];
+    }
+
+    store[idx] = fix;
+    Tcl_IncrRefCount(fix);
+    TclNRAddCallback(interp, TclNRReleaseValues, fix, NULL, NULL, NULL);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFetchEnsembleRoot --
+ *
+ *     Returns the root of ensemble rewriting, if any.
+ *     If no root exists, returns objv instead.
+ *
+ * Results:
+ *     None.
+ *
+ * Side effects:
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *const *
+TclFetchEnsembleRoot(
+    Tcl_Interp *interp,
+    Tcl_Obj *const *objv,
+    int objc,
+    int *objcPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (iPtr->ensembleRewrite.sourceObjs) {
+       *objcPtr = objc + iPtr->ensembleRewrite.numRemovedObjs
+               - iPtr->ensembleRewrite.numInsertedObjs;
+       return iPtr->ensembleRewrite.sourceObjs;
+    }
+    *objcPtr = objc;
+    return objv;
+}
+\f
+/*
  * ----------------------------------------------------------------------
  *
  * EnsmebleUnknownCallback --
@@ -2218,17 +2341,17 @@ static void
 MakeCachedEnsembleCommand(
     Tcl_Obj *objPtr,
     EnsembleConfig *ensemblePtr,
-    const char *subcommandName,
-    Tcl_Obj *prefixObjPtr)
+    Tcl_HashEntry *hPtr,
+    Tcl_Obj *fix)
 {
     register EnsembleCmdRep *ensembleCmd;
-    int length;
 
-    if (objPtr->typePtr == &tclEnsembleCmdType) {
+    if (objPtr->typePtr == &ensembleCmdType) {
        ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
-       Tcl_DecrRefCount(ensembleCmd->realPrefixObj);
-       TclNsDecrRefCount(ensembleCmd->nsPtr);
-       ckfree(ensembleCmd->fullSubcmdName);
+       TclCleanupCommandMacro(ensembleCmd->token);
+       if (ensembleCmd->fix) {
+           Tcl_DecrRefCount(ensembleCmd->fix);
+       }
     } else {
        /*
         * Kill the old internal rep, and replace it with a brand new one of
@@ -2238,22 +2361,21 @@ MakeCachedEnsembleCommand(
        TclFreeIntRep(objPtr);
        ensembleCmd = ckalloc(sizeof(EnsembleCmdRep));
        objPtr->internalRep.twoPtrValue.ptr1 = ensembleCmd;
-       objPtr->typePtr = &tclEnsembleCmdType;
+       objPtr->typePtr = &ensembleCmdType;
     }
 
     /*
      * Populate the internal rep.
      */
 
-    ensembleCmd->nsPtr = ensemblePtr->nsPtr;
     ensembleCmd->epoch = ensemblePtr->epoch;
-    ensembleCmd->token = ensemblePtr->token;
-    ensemblePtr->nsPtr->refCount++;
-    ensembleCmd->realPrefixObj = prefixObjPtr;
-    length = strlen(subcommandName)+1;
-    ensembleCmd->fullSubcmdName = ckalloc(length);
-    memcpy(ensembleCmd->fullSubcmdName, subcommandName, (unsigned) length);
-    Tcl_IncrRefCount(ensembleCmd->realPrefixObj);
+    ensembleCmd->token = (Command *) ensemblePtr->token;
+    ensembleCmd->token->refCount++;
+    if (fix) {
+       Tcl_IncrRefCount(fix);
+    }
+    ensembleCmd->fix = fix;
+    ensembleCmd->hPtr = hPtr;
 }
 \f
 /*
@@ -2634,9 +2756,10 @@ FreeEnsembleCmdRep(
 {
     EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
 
-    Tcl_DecrRefCount(ensembleCmd->realPrefixObj);
-    ckfree(ensembleCmd->fullSubcmdName);
-    TclNsDecrRefCount(ensembleCmd->nsPtr);
+    TclCleanupCommandMacro(ensembleCmd->token);
+    if (ensembleCmd->fix) {
+       Tcl_DecrRefCount(ensembleCmd->fix);
+    }
     ckfree(ensembleCmd);
     objPtr->typePtr = NULL;
 }
@@ -2666,48 +2789,17 @@ DupEnsembleCmdRep(
 {
     EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
     EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep));
-    int length = strlen(ensembleCmd->fullSubcmdName);
 
-    copyPtr->typePtr = &tclEnsembleCmdType;
+    copyPtr->typePtr = &ensembleCmdType;
     copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy;
-    ensembleCopy->nsPtr = ensembleCmd->nsPtr;
     ensembleCopy->epoch = ensembleCmd->epoch;
     ensembleCopy->token = ensembleCmd->token;
-    ensembleCopy->nsPtr->refCount++;
-    ensembleCopy->realPrefixObj = ensembleCmd->realPrefixObj;
-    Tcl_IncrRefCount(ensembleCopy->realPrefixObj);
-    ensembleCopy->fullSubcmdName = ckalloc(length + 1);
-    memcpy(ensembleCopy->fullSubcmdName, ensembleCmd->fullSubcmdName,
-           (unsigned) length+1);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * StringOfEnsembleCmdRep --
- *
- *     Creates a string representation of a Tcl_Obj that holds a subcommand
- *     of an ensemble.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     The object gains a string (UTF-8) representation.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-StringOfEnsembleCmdRep(
-    Tcl_Obj *objPtr)
-{
-    EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
-    int length = strlen(ensembleCmd->fullSubcmdName);
-
-    objPtr->length = length;
-    objPtr->bytes = ckalloc(length + 1);
-    memcpy(objPtr->bytes, ensembleCmd->fullSubcmdName, (unsigned) length+1);
+    ensembleCopy->token->refCount++;
+    ensembleCopy->fix = ensembleCmd->fix;
+    if (ensembleCopy->fix) {
+       Tcl_IncrRefCount(ensembleCopy->fix);
+    }
+    ensembleCopy->hPtr = ensembleCmd->hPtr;
 }
 \f
 /*
@@ -3082,6 +3174,11 @@ TclAttemptCompileProc(
     Tcl_Token *saveTokenPtr = parsePtr->tokenPtr;
     int savedStackDepth = envPtr->currStackDepth;
     unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart;
+    int savedAuxDataArrayNext = envPtr->auxDataArrayNext;
+    int savedExceptArrayNext = envPtr->exceptArrayNext;
+#ifdef TCL_COMPILE_DEBUG
+    int savedExceptDepth = envPtr->exceptDepth;
+#endif
     DefineLineInformation;
 
     if (cmdPtr->compileProc == NULL) {
@@ -3130,7 +3227,45 @@ TclAttemptCompileProc(
      * we avoid compiling subcommands that recursively call TclCompileScript().
      */
 
+#ifdef TCL_COMPILE_DEBUG
+    if (envPtr->exceptDepth != savedExceptDepth) {
+       Tcl_Panic("ExceptionRange Starts and Ends do not balance");
+    }
+#endif
+
     if (result != TCL_OK) {
+       ExceptionAux *auxPtr = envPtr->exceptAuxArrayPtr;
+
+       for (i = 0; i < savedExceptArrayNext; i++) {
+           while (auxPtr->numBreakTargets > 0
+                   && auxPtr->breakTargets[auxPtr->numBreakTargets - 1]
+                   >= savedCodeNext) {
+               auxPtr->numBreakTargets--;
+           }
+           while (auxPtr->numContinueTargets > 0
+                   && auxPtr->continueTargets[auxPtr->numContinueTargets - 1]
+                   >= savedCodeNext) {
+               auxPtr->numContinueTargets--;
+           }
+           auxPtr++;
+       }
+       envPtr->exceptArrayNext = savedExceptArrayNext;
+
+       if (savedAuxDataArrayNext != envPtr->auxDataArrayNext) {
+           AuxData *auxDataPtr = envPtr->auxDataArrayPtr;
+           AuxData *auxDataEnd = auxDataPtr;
+
+           auxDataPtr += savedAuxDataArrayNext;
+           auxDataEnd += envPtr->auxDataArrayNext;
+
+           while (auxDataPtr < auxDataEnd) {
+               if (auxDataPtr->type->freeProc != NULL) {
+                   auxDataPtr->type->freeProc(auxDataPtr->clientData);
+               }
+               auxDataPtr++;
+           }
+           envPtr->auxDataArrayNext = savedAuxDataArrayNext;
+       }
        envPtr->currStackDepth = savedStackDepth;
        envPtr->codeNext = envPtr->codeStart + savedCodeNext;
 #ifdef TCL_COMPILE_DEBUG
index 8305410..b0b8188 100644 (file)
@@ -1462,6 +1462,8 @@ VwaitVarProc(
     int *donePtr = clientData;
 
     *donePtr = 1;
+    Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+           VwaitVarProc, clientData);
     return NULL;
 }
 \f
index dacc9e2..e539161 100644 (file)
@@ -19,6 +19,7 @@
 #include "tclCompile.h"
 #include "tclOOInt.h"
 #include "tommath.h"
+#include "tclStringRep.h"
 #include <math.h>
 #include <assert.h>
 
@@ -2077,6 +2078,13 @@ TclNRExecuteByteCode(
 #endif
 
     /*
+     * Test namespace-50.9 demonstrates the need for this call.
+     * Use a --enable-symbols=mem bug to see.
+     */
+
+    TclResetRewriteEnsemble(interp, 1);
+
+    /*
      * Push the callback for bytecode execution
      */
 
@@ -3152,35 +3160,34 @@ TEBCresume(
            fflush(stdout);
        }
 #endif /*TCL_COMPILE_DEBUG*/
-       {
-           Tcl_Obj *copyPtr = Tcl_NewListObj(objc - opnd + 1, NULL);
-           register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1;
-           Tcl_Obj **copyObjv = &listRepPtr->elements;
-           int i;
 
-           listRepPtr->elemCount = objc - opnd + 1;
-           copyObjv[0] = objPtr;
-           memcpy(copyObjv+1, objv+opnd, sizeof(Tcl_Obj *) * (objc - opnd));
-           for (i=1 ; i<objc-opnd+1 ; i++) {
-               Tcl_IncrRefCount(copyObjv[i]);
-           }
-           objPtr = copyPtr;
-       }
        bcFramePtr->data.tebc.pc = (char *) pc;
        iPtr->cmdFramePtr = bcFramePtr;
        if (iPtr->flags & INTERP_DEBUG_FRAME) {
            ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
        }
-       iPtr->ensembleRewrite.sourceObjs = objv;
-       iPtr->ensembleRewrite.numRemovedObjs = opnd;
-       iPtr->ensembleRewrite.numInsertedObjs = 1;
+
+       TclInitRewriteEnsemble(interp, opnd, 1, objv);
+
+       {
+           Tcl_Obj *copyPtr = Tcl_NewListObj(objc - opnd + 1, NULL);
+
+           Tcl_ListObjAppendElement(NULL, copyPtr, objPtr);
+           Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0, 
+                   objc - opnd, objv + opnd);
+           Tcl_DecrRefCount(objPtr);
+           objPtr = copyPtr;
+       }
+
        DECACHE_STACK_INFO();
        pc += 6;
        TEBC_YIELD();
 
        TclMarkTailcall(interp);
-       TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL);
-       return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN);
+       TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+       Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv);
+       TclNRAddCallback(interp, TclNRReleaseValues, objPtr, NULL, NULL, NULL);
+       return TclNREvalObjv(interp, objc, objv, TCL_EVAL_INVOKE, NULL);
 
     /*
      * -----------------------------------------------------------------
@@ -4413,8 +4420,8 @@ TEBCresume(
        savedNsPtr = iPtr->varFramePtr->nsPtr;
        iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
        otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
-               (TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
-               /*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
+               (TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
+               "access", /*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
        iPtr->varFramePtr->nsPtr = savedNsPtr;
        if (!otherPtr) {
            TRACE_ERROR(interp);
@@ -5737,6 +5744,16 @@ TEBCresume(
        if (length3 - 1 == toIdx - fromIdx) {
            unsigned char *bytes1, *bytes2;
 
+           /*
+            * Flush the info in the string internal rep that refers to the
+            * about-to-be-invalidated UTF-8 rep. This indicates that a new
+            * buffer needs to be allocated, and assumes that the value is
+            * already of tclStringTypePtr type, which should be true provided
+            * we call it after Tcl_GetUnicodeFromObj.
+            */
+#define MarkStringInternalRepForFlush(objPtr) \
+           (GET_STRING(objPtr)->allocated = 0)
+
            if (Tcl_IsShared(valuePtr)) {
                objResultPtr = Tcl_DuplicateObj(valuePtr);
                if (TclIsPureByteArray(objResultPtr)
@@ -5749,17 +5766,7 @@ TEBCresume(
                    ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
                    memcpy(ustring1 + fromIdx, ustring2,
                            length3 * sizeof(Tcl_UniChar));
-
-                   /*
-                    * Magic! Flush the info in the string internal rep that
-                    * refers to the about-to-be-invalidated UTF-8 rep. This
-                    * sets the 'allocated' field of the String structure to 0
-                    * to indicate that a new buffer needs to be allocated.
-                    * This is safe; we know we've got a tclStringTypePtr set
-                    * at this point (post Tcl_GetUnicodeFromObj).
-                    */
-
-                   ((int *) objResultPtr->internalRep.twoPtrValue.ptr1)[1] = 0;
+                   MarkStringInternalRepForFlush(objResultPtr);
                }
                Tcl_InvalidateStringRep(objResultPtr);
                TclDecrRefCount(value3Ptr);
@@ -5776,17 +5783,7 @@ TEBCresume(
                    ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
                    memcpy(ustring1 + fromIdx, ustring2,
                            length3 * sizeof(Tcl_UniChar));
-
-                   /*
-                    * Magic! Flush the info in the string internal rep that
-                    * refers to the about-to-be-invalidated UTF-8 rep. This
-                    * sets the 'allocated' field of the String structure to 0
-                    * to indicate that a new buffer needs to be allocated.
-                    * This is safe; we know we've got a tclStringTypePtr set
-                    * at this point (post Tcl_GetUnicodeFromObj).
-                    */
-
-                   ((int *) objResultPtr->internalRep.twoPtrValue.ptr1)[1] = 0;
+                   MarkStringInternalRepForFlush(valuePtr);
                }
                Tcl_InvalidateStringRep(valuePtr);
                TclDecrRefCount(value3Ptr);
@@ -7715,6 +7712,7 @@ TEBCresume(
                goto gotError;
            }
        }
+       Tcl_IncrRefCount(dictPtr);
        if (TclListObjGetElements(interp, OBJ_AT_TOS, &length,
                &keyPtrPtr) != TCL_OK) {
            TRACE_ERROR(interp);
@@ -7727,6 +7725,7 @@ TEBCresume(
            if (Tcl_DictObjGet(interp, dictPtr, keyPtrPtr[i],
                    &valuePtr) != TCL_OK) {
                TRACE_ERROR(interp);
+               Tcl_DecrRefCount(dictPtr);
                goto gotError;
            }
            varPtr = LOCAL(duiPtr->varIndices[i]);
@@ -7743,10 +7742,12 @@ TEBCresume(
                    duiPtr->varIndices[i]) == NULL) {
                CACHE_STACK_INFO();
                TRACE_ERROR(interp);
+               Tcl_DecrRefCount(dictPtr);
                goto gotError;
            }
            CACHE_STACK_INFO();
        }
+       TclDecrRefCount(dictPtr);
        TRACE_APPEND(("OK\n"));
        NEXT_INST_F(9, 0, 0);
 
index 39bac99..2136883 100644 (file)
@@ -1595,8 +1595,9 @@ Tcl_GlobObjCmd(
     } else if (dir == PATH_GENERAL) {
        Tcl_DString str;
 
+       Tcl_DStringInit(&str);
        for (i = 0; i < objc; i++) {
-           Tcl_DStringInit(&str);
+           Tcl_DStringSetLength(&str, 0);
            if (dir == PATH_GENERAL) {
                TclDStringAppendDString(&str, &prefix);
            }
index f93d00d..80f6fa4 100644 (file)
@@ -313,15 +313,20 @@ static int              WillRead(Channel *chanPtr);
                && (strncmp(optionName, (nameString), len) == 0))
 
 /*
- * The ChannelObjType type.  We actually store the ChannelState structure
- * as that lives longest and we want to return the bottomChanPtr when
- * requested (consistent with Tcl_GetChannel).  The setFromAny and
- * updateString can be NULL as they should not be called.
+ * The ChannelObjType type.  Used to store the result of looking up
+ * a channel name in the context of an interp.  Saves the lookup
+ * result and values needed to check its continued validity.
  */
 
+typedef struct ResolvedChanName {
+    ChannelState *statePtr;    /* The saved lookup result */
+    Tcl_Interp *interp;                /* The interp in which the lookup was done. */
+    int epoch;                 /* The epoch of the channel when the lookup
+                                * was done. Use to verify validity. */
+    int refCount;              /* Share this struct among many Tcl_Obj. */
+} ResolvedChanName;
+
 static void            DupChannelIntRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
-static int             SetChannelFromAny(Tcl_Interp *interp,
-                           Tcl_Obj *objPtr);
 static void            FreeChannelIntRep(Tcl_Obj *objPtr);
 
 static const Tcl_ObjType chanObjType = {
@@ -329,18 +334,9 @@ static const Tcl_ObjType chanObjType = {
     FreeChannelIntRep,         /* freeIntRepProc */
     DupChannelIntRep,          /* dupIntRepProc */
     NULL,                      /* updateStringProc */
-    NULL                       /* setFromAnyProc SetChannelFromAny */
+    NULL                       /* setFromAnyProc */
 };
 
-#define GET_CHANNELSTATE(objPtr) \
-    ((ChannelState *) (objPtr)->internalRep.twoPtrValue.ptr1)
-#define SET_CHANNELSTATE(objPtr, storePtr) \
-    ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (storePtr))
-#define GET_CHANNELINTERP(objPtr) \
-    ((Tcl_Interp *) (objPtr)->internalRep.twoPtrValue.ptr2)
-#define SET_CHANNELINTERP(objPtr, storePtr) \
-    ((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (storePtr))
-
 #define BUSY_STATE(st, fl) \
      ((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \
       (((st)->csPtrW) && ((fl) & TCL_WRITABLE)))
@@ -1021,7 +1017,7 @@ DeleteChannelTable(
         */
 
        Tcl_DeleteHashEntry(hPtr);
-       SetFlag(statePtr, CHANNEL_TAINTED);
+       statePtr->epoch++;
        if (statePtr->refCount-- <= 1) {
            if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
                (void) Tcl_Close(interp, (Tcl_Channel) chanPtr);
@@ -1365,7 +1361,7 @@ DetachChannel(
            return TCL_ERROR;
        }
        Tcl_DeleteHashEntry(hPtr);
-       SetFlag(statePtr, CHANNEL_TAINTED);
+       statePtr->epoch++;
 
        /*
         * Remove channel handlers that refer to this interpreter, so that
@@ -1498,12 +1494,57 @@ TclGetChannelFromObj(
     int flags)
 {
     ChannelState *statePtr;
+    ResolvedChanName *resPtr = NULL;
+    Tcl_Channel chan;
+
+    if (interp == NULL) {
+       return TCL_ERROR;
+    }
+
+    if (objPtr->typePtr == &chanObjType) {
+       /*
+        * Confirm validity of saved lookup results.
+        */
+
+       resPtr = (ResolvedChanName *) objPtr->internalRep.twoPtrValue.ptr1;
+       statePtr = resPtr->statePtr;
+       if ((resPtr->interp == interp)          /* Same interp context */
+                       /* No epoch change in channel since lookup */
+               && (resPtr->epoch == statePtr->epoch)) {
+
+           /* Have a valid saved lookup. Jump to end to return it. */
+           goto valid;
+       }
+    }
+
+    chan = Tcl_GetChannel(interp, TclGetString(objPtr), NULL);
 
-    if (SetChannelFromAny(interp, objPtr) != TCL_OK) {
+    if (chan == NULL) {
+       if (resPtr) {
+           FreeChannelIntRep(objPtr);
+       }
        return TCL_ERROR;
     }
 
-    statePtr = GET_CHANNELSTATE(objPtr);
+    if (resPtr && resPtr->refCount == 1) {
+       /* Re-use the ResolvedCmdName struct */
+       Tcl_Release((ClientData) resPtr->statePtr);
+
+    } else {
+       TclFreeIntRep(objPtr);
+
+       resPtr = (ResolvedChanName *) ckalloc(sizeof(ResolvedChanName));
+       resPtr->refCount = 1;
+       objPtr->internalRep.twoPtrValue.ptr1 = (ClientData) resPtr;
+       objPtr->typePtr = &chanObjType;
+    }
+    statePtr = ((Channel *)chan)->state;
+    resPtr->statePtr = statePtr;
+    Tcl_Preserve((ClientData) statePtr);
+    resPtr->interp = interp;
+    resPtr->epoch = statePtr->epoch;
+
+  valid:
     *channelPtr = (Tcl_Channel) statePtr->bottomChanPtr;
 
     if (modePtr != NULL) {
@@ -1676,6 +1717,8 @@ Tcl_CreateChannel(
     statePtr->chanMsg          = NULL;
     statePtr->unreportedMsg    = NULL;
 
+    statePtr->epoch            = 0;
+
     /*
      * Link the channel into the list of all channels; create an on-exit
      * handler if there is not one already, to close off all the channels in
@@ -11121,78 +11164,16 @@ DupChannelIntRep(
     register Tcl_Obj *copyPtr) /* Object with internal rep to set. Must not
                                 * currently have an internal rep.*/
 {
-    ChannelState *statePtr  = GET_CHANNELSTATE(srcPtr);
+    ResolvedChanName *resPtr = srcPtr->internalRep.twoPtrValue.ptr1;
 
-    SET_CHANNELSTATE(copyPtr, statePtr);
-    SET_CHANNELINTERP(copyPtr, GET_CHANNELINTERP(srcPtr));
-    Tcl_Preserve(statePtr);
+    resPtr->refCount++;
+    copyPtr->internalRep.twoPtrValue.ptr1 = resPtr;
     copyPtr->typePtr = srcPtr->typePtr;
 }
 \f
 /*
  *----------------------------------------------------------------------
  *
- * SetChannelFromAny --
- *
- *     Create an internal representation of type "Channel" for an object.
- *
- * Results:
- *     This operation always succeeds and returns TCL_OK.
- *
- * Side effects:
- *     Any old internal reputation for objPtr is freed and the internal
- *     representation is set to "Channel".
- *
- *----------------------------------------------------------------------
- */
-
-static int
-SetChannelFromAny(
-    Tcl_Interp *interp,                /* Used for error reporting if not NULL. */
-    register Tcl_Obj *objPtr)  /* The object to convert. */
-{
-    ChannelState *statePtr;
-
-    if (interp == NULL) {
-       return TCL_ERROR;
-    }
-    if (objPtr->typePtr == &chanObjType) {
-       /*
-        * TODO: TAINT Flag and dup'd channel values?
-        * The channel is valid until any call to DetachChannel occurs.
-        * Ensure consistency checks are done.
-        */
-
-       statePtr = GET_CHANNELSTATE(objPtr);
-       if (GotFlag(statePtr, CHANNEL_TAINTED|CHANNEL_CLOSED)) {
-           ResetFlag(statePtr, CHANNEL_TAINTED);
-           Tcl_Release(statePtr);
-           objPtr->typePtr = NULL;
-       } else if (interp != GET_CHANNELINTERP(objPtr)) {
-           Tcl_Release(statePtr);
-           objPtr->typePtr = NULL;
-       }
-    }
-    if (objPtr->typePtr != &chanObjType) {
-       Tcl_Channel chan = Tcl_GetChannel(interp, TclGetString(objPtr), NULL);
-
-       if (chan == NULL) {
-           return TCL_ERROR;
-       }
-
-       TclFreeIntRep(objPtr);
-       statePtr = ((Channel *) chan)->state;
-       Tcl_Preserve(statePtr);
-       SET_CHANNELSTATE(objPtr, statePtr);
-       SET_CHANNELINTERP(objPtr, interp);
-       objPtr->typePtr = &chanObjType;
-    }
-    return TCL_OK;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
  * FreeChannelIntRep --
  *
  *     Release statePtr storage.
@@ -11210,8 +11191,14 @@ static void
 FreeChannelIntRep(
     Tcl_Obj *objPtr)           /* Object with internal rep to free. */
 {
-    Tcl_Release(GET_CHANNELSTATE(objPtr));
+    ResolvedChanName *resPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
     objPtr->typePtr = NULL;
+    if (--resPtr->refCount) {
+       return;
+    }
+    Tcl_Release(resPtr->statePtr);
+    ckfree(resPtr);
 }
 \f
 #if 0
index b799375..ffbfa31 100644 (file)
@@ -214,6 +214,8 @@ typedef struct ChannelState {
                                 * because it happened in the background. The
                                 * value is the chanMg, if any. #219's
                                 * companion to 'unreportedError'. */
+    int epoch;                 /* Used to test validity of stored channelname
+                                * lookup results. */
 } ChannelState;
 
 /*
@@ -275,10 +277,6 @@ typedef struct ChannelState {
                                         * usable, but it may not be closed
                                         * again from within the close
                                         * handler. */
-#define CHANNEL_TAINTED                (1<<20) /* Channel stack structure has changed.
-                                        * Used by Channel Tcl_Obj type to
-                                        * determine if we have to revalidate
-                                        * the channel. */
 #define CHANNEL_CLOSEDWRITE    (1<<21) /* Channel write side has been closed.
                                         * No further Tcl-level write IO on
                                         * the channel is allowed. */
index 21c766e..f476a1a 100644 (file)
@@ -1609,8 +1609,6 @@ ReflectWatch(
        return;
     }
 
-    rcPtr->interest = mask;
-
     /*
      * Are we in the correct thread?
      */
@@ -1633,6 +1631,7 @@ ReflectWatch(
 
     Tcl_Preserve(rcPtr);
 
+    rcPtr->interest = mask;
     maskObj = DecodeEventMask(mask);
     /* assert maskObj.refCount == 1 */
     (void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
@@ -3083,6 +3082,7 @@ ForwardProc(
         /* assert maskObj.refCount == 1 */
 
         Tcl_Preserve(rcPtr);
+       rcPtr->interest = paramPtr->watch.mask;
        (void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
        Tcl_DecrRefCount(maskObj);
         Tcl_Release(rcPtr);
index 1330c02..3aa0ce5 100644 (file)
@@ -71,8 +71,7 @@ typedef struct ThreadSpecificData {
  * Prototypes for functions defined later in this file.
  */
 
-static int             EvalFileCallback(ClientData data[],
-                           Tcl_Interp *interp, int result);
+static Tcl_NRPostProc  EvalFileCallback;
 static FilesystemRecord*FsGetFirstFilesystem(void);
 static void            FsThrExitProc(ClientData cd);
 static Tcl_Obj *       FsListMounts(Tcl_Obj *pathPtr, const char *pattern);
index ce8b9fb..0e0ddc9 100644 (file)
@@ -925,6 +925,14 @@ Tcl_WrongNumArgs(
        Tcl_Obj *const *origObjv = iPtr->ensembleRewrite.sourceObjs;
 
        /*
+        * Check for spelling fixes, and substitute the fixed values.
+        */
+
+       if (origObjv[0] == NULL) {
+           origObjv = (Tcl_Obj *const *)origObjv[2];
+       }
+
+       /*
         * We only know how to do rewriting if all the replaced objects are
         * actually arguments (in objv) to this function. Otherwise it just
         * gets too complicated and we'd be better off just giving a slightly
@@ -957,12 +965,6 @@ Tcl_WrongNumArgs(
 
                elementStr = EXPAND_OF(indexRep);
                elemLen = strlen(elementStr);
-           } else if (origObjv[i]->typePtr == &tclEnsembleCmdType) {
-               register EnsembleCmdRep *ecrPtr =
-                       origObjv[i]->internalRep.twoPtrValue.ptr1;
-
-               elementStr = ecrPtr->fullSubcmdName;
-               elemLen = strlen(elementStr);
            } else {
                elementStr = TclGetStringFromObj(origObjv[i], &elemLen);
            }
@@ -1011,11 +1013,6 @@ Tcl_WrongNumArgs(
            register IndexRep *indexRep = objv[i]->internalRep.twoPtrValue.ptr1;
 
            Tcl_AppendStringsToObj(objPtr, EXPAND_OF(indexRep), NULL);
-       } else if (objv[i]->typePtr == &tclEnsembleCmdType) {
-           register EnsembleCmdRep *ecrPtr =
-                   objv[i]->internalRep.twoPtrValue.ptr1;
-
-           Tcl_AppendStringsToObj(objPtr, ecrPtr->fullSubcmdName, NULL);
        } else {
            /*
             * Quote the argument if it contains spaces (Bug 942757).
index 42c13dd..4f7ea6e 100644 (file)
@@ -48,7 +48,8 @@
 #else
 #include <string.h>
 #endif
-#ifdef STDC_HEADERS
+#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
+     || defined(__cplusplus) || defined(_MSC_VER)
 #include <stddef.h>
 #else
 typedef int ptrdiff_t;
@@ -169,6 +170,21 @@ typedef struct Tcl_ResolverInfo {
 } Tcl_ResolverInfo;
 
 /*
+ * This flag bit should not interfere with TCL_GLOBAL_ONLY,
+ * TCL_NAMESPACE_ONLY, or TCL_LEAVE_ERR_MSG; it signals that the variable
+ * lookup is performed for upvar (or similar) purposes, with slightly
+ * different rules:
+ *    - Bug #696893 - variable is either proc-local or in the current
+ *     namespace; never follow the second (global) resolution path
+ *    - Bug #631741 - do not use special namespace or interp resolvers
+ *
+ * It should also not collide with the (deprecated) TCL_PARSE_PART1 flag
+ * (Bug #835020)
+ */
+
+#define TCL_AVOID_RESOLVERS 0x40000
+
+/*
  *----------------------------------------------------------------
  * Data structures related to namespaces.
  *----------------------------------------------------------------
@@ -389,27 +405,6 @@ struct NamespacePathEntry {
 #define TCL_FIND_ONLY_NS               0x1000
 
 /*
- * The data cached in an ensemble subcommand's Tcl_Obj rep (reference in
- * twoPtrValue.ptr1 field). This structure is not shared between Tcl_Objs
- * referring to the same subcommand, even where one is a duplicate of another.
- */
-
-typedef struct {
-    Namespace *nsPtr;          /* The namespace backing the ensemble which
-                                * this is a subcommand of. */
-    int epoch;                 /* Used to confirm when the data in this
-                                * really structure matches up with the
-                                * ensemble. */
-    Tcl_Command token;         /* Reference to the comamnd for which this
-                                * structure is a cache of the resolution. */
-    char *fullSubcmdName;      /* The full (local) name of the subcommand,
-                                * allocated with ckalloc(). */
-    Tcl_Obj *realPrefixObj;    /* Object containing the prefix words of the
-                                * command that implements this ensemble
-                                * subcommand. */
-} EnsembleCmdRep;
-
-/*
  * The client data for an ensemble command. This consists of the table of
  * commands that are actually exported by the namespace, and an epoch counter
  * that, combined with the exportLookupEpoch field of the namespace structure,
@@ -2761,6 +2756,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd;
 MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd;
 MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd;
 MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke;
+MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues;
 
 MODULE_SCOPE void  TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr);
 MODULE_SCOPE void  TclPushTailcallPoint(Tcl_Interp *interp);
@@ -2871,8 +2867,7 @@ MODULE_SCOPE int  TclCheckBadOctal(Tcl_Interp *interp,
 MODULE_SCOPE int       TclChanCaughtErrorBypass(Tcl_Interp *interp,
                            Tcl_Channel chan);
 MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd;
-MODULE_SCOPE int       TclClearRootEnsemble(ClientData data[],
-                           Tcl_Interp *interp, int result);
+MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble;
 MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num,
                            int *loc);
 MODULE_SCOPE void      TclContinuationsEnterDerived(Tcl_Obj *objPtr,
@@ -2908,6 +2903,8 @@ MODULE_SCOPE char *       TclDStringAppendObj(Tcl_DString *dsPtr,
 MODULE_SCOPE char *    TclDStringAppendDString(Tcl_DString *dsPtr,
                            Tcl_DString *toAppendPtr);
 MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr);
+MODULE_SCOPE Tcl_Obj *const *  TclFetchEnsembleRoot(Tcl_Interp *interp,
+                           Tcl_Obj *const *objv, int objc, int *objcPtr);
 MODULE_SCOPE void      TclFinalizeAllocSubsystem(void);
 MODULE_SCOPE void      TclFinalizeAsync(void);
 MODULE_SCOPE void      TclFinalizeDoubleConversion(void);
@@ -3110,6 +3107,9 @@ MODULE_SCOPE void TclSetDuplicateObj(Tcl_Obj *dupPtr, Tcl_Obj *objPtr);
 MODULE_SCOPE void      TclSetProcessGlobalValue(ProcessGlobalValue *pgvPtr,
                            Tcl_Obj *newValue, Tcl_Encoding encoding);
 MODULE_SCOPE void      TclSignalExitThread(Tcl_ThreadId id, int result);
+MODULE_SCOPE void      TclSpellFix(Tcl_Interp *interp,
+                           Tcl_Obj *const *objv, int objc, int subIdx,
+                           Tcl_Obj *bad, Tcl_Obj *fix);
 MODULE_SCOPE void *    TclStackRealloc(Tcl_Interp *interp, void *ptr,
                            int numBytes);
 MODULE_SCOPE int       TclStringMatch(const char *str, int strLen,
index 5c94461..66ce1e0 100644 (file)
@@ -723,7 +723,7 @@ NRInterpCmd(
        }
 
     endOfForLoop:
-       if ((i + 2) < objc) {
+       if (i < objc - 2) {
            Tcl_WrongNumArgs(interp, 2, objv,
                    "?-unwind? ?--? ?path? ?result?");
            return TCL_ERROR;
@@ -1795,11 +1795,9 @@ AliasNRCmd(
     int objc,                  /* Number of arguments. */
     Tcl_Obj *const objv[])     /* Argument vector. */
 {
-    Interp *iPtr = (Interp *) interp;
     Alias *aliasPtr = clientData;
     int prefc, cmdc, i;
     Tcl_Obj **prefv, **cmdv;
-    int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
     Tcl_Obj *listPtr;
     List *listRep;
     int flags = TCL_EVAL_INVOKE;
@@ -1831,21 +1829,7 @@ AliasNRCmd(
      * only the source command should show, not the full target prefix.
      */
 
-    if (isRootEnsemble) {
-       iPtr->ensembleRewrite.sourceObjs = objv;
-       iPtr->ensembleRewrite.numRemovedObjs = 1;
-       iPtr->ensembleRewrite.numInsertedObjs = prefc;
-    } else {
-       iPtr->ensembleRewrite.numInsertedObjs += prefc - 1;
-    }
-
-    /*
-     * We are sending a 0-refCount obj, do not need a callback: it will be
-     * cleaned up automatically. But we may need to clear the rootEnsemble
-     * stuff ...
-     */
-
-    if (isRootEnsemble) {
+    if (TclInitRewriteEnsemble(interp, 1, prefc, objv)) {
        TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
     }
     TclSkipTailcall(interp);
@@ -1866,7 +1850,7 @@ AliasObjCmd(
     Tcl_Obj **prefv, **cmdv;
     Tcl_Obj *cmdArr[ALIAS_CMDV_PREALLOC];
     Interp *tPtr = (Interp *) targetInterp;
-    int isRootEnsemble = (tPtr->ensembleRewrite.sourceObjs == NULL);
+    int isRootEnsemble;
 
     /*
      * Append the arguments to the command prefix and invoke the command in
@@ -1896,13 +1880,7 @@ AliasObjCmd(
      * only the source command should show, not the full target prefix.
      */
 
-    if (isRootEnsemble) {
-       tPtr->ensembleRewrite.sourceObjs = objv;
-       tPtr->ensembleRewrite.numRemovedObjs = 1;
-       tPtr->ensembleRewrite.numInsertedObjs = prefc;
-    } else {
-       tPtr->ensembleRewrite.numInsertedObjs += prefc - 1;
-    }
+    isRootEnsemble = TclInitRewriteEnsemble((Tcl_Interp *)tPtr, 1, prefc, objv);
 
     /*
      * Protect the target interpreter if it isn't the same as the source
@@ -1925,9 +1903,7 @@ AliasObjCmd(
      */
 
     if (isRootEnsemble) {
-       tPtr->ensembleRewrite.sourceObjs = NULL;
-       tPtr->ensembleRewrite.numRemovedObjs = 0;
-       tPtr->ensembleRewrite.numInsertedObjs = 0;
+       TclResetRewriteEnsemble((Tcl_Interp *)tPtr, 1);
     }
 
     /*
index dfab185..5930859 100644 (file)
@@ -1105,8 +1105,6 @@ TclTeardownNamespace(
     Interp *iPtr = (Interp *) nsPtr->interp;
     register Tcl_HashEntry *entryPtr;
     Tcl_HashSearch search;
-    Tcl_Namespace *childNsPtr;
-    Tcl_Command cmd;
     int i;
 
     /*
@@ -1121,16 +1119,31 @@ TclTeardownNamespace(
     /*
      * Delete all commands in this namespace. Be careful when traversing the
      * hash table: when each command is deleted, it removes itself from the
-     * command table.
-     *
-     * Don't optimize to Tcl_NextHashEntry() because of traces.
+     * command table. Because of traces (and the desire to avoid the quadratic
+     * problems of just using Tcl_FirstHashEntry over and over, [Bug
+     * f97d4ee020]) we copy to a temporary array and then delete all those
+     * commands.
      */
 
-    for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
-           entryPtr != NULL;
-           entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search)) {
-       cmd = Tcl_GetHashValue(entryPtr);
-       Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr, cmd);
+    while (nsPtr->cmdTable.numEntries > 0) {
+       int length = nsPtr->cmdTable.numEntries;
+       Command **cmds = TclStackAlloc((Tcl_Interp *) iPtr,
+               sizeof(Command *) * length);
+
+       i = 0;
+       for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+               entryPtr != NULL;
+               entryPtr = Tcl_NextHashEntry(&search)) {
+           cmds[i] = Tcl_GetHashValue(entryPtr);
+           cmds[i]->refCount++;
+           i++;
+       }
+       for (i = 0 ; i < length ; i++) {
+           Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr,
+                   (Tcl_Command) cmds[i]);
+           TclCleanupCommandMacro(cmds[i]);
+       }
+       TclStackFree((Tcl_Interp *) iPtr, cmds);
     }
     Tcl_DeleteHashTable(&nsPtr->cmdTable);
     Tcl_InitHashTable(&nsPtr->cmdTable, TCL_STRING_KEYS);
@@ -1175,25 +1188,54 @@ TclTeardownNamespace(
      *
      * BE CAREFUL: When each child is deleted, it will divorce itself from its
      * parent. You can't traverse a hash table properly if its elements are
-     * being deleted. We use only the Tcl_FirstHashEntry function to be safe.
+     * being deleted.  Because of traces (and the desire to avoid the
+     * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug
+     * f97d4ee020]) we copy to a temporary array and then delete all those
+     * namespaces.
      *
-     * Don't optimize to Tcl_NextHashEntry() because of traces.
+     * Important: leave the hash table itself still live.
      */
 
 #ifndef BREAK_NAMESPACE_COMPAT
-    for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
-           entryPtr != NULL;
-           entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search)) {
-       childNsPtr = Tcl_GetHashValue(entryPtr);
-       Tcl_DeleteNamespace(childNsPtr);
+    while (nsPtr->childTable.numEntries > 0) {
+       int length = nsPtr->childTable.numEntries;
+       Namespace **children = TclStackAlloc((Tcl_Interp *) iPtr,
+               sizeof(Namespace *) * length);
+
+       i = 0;
+       for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
+               entryPtr != NULL;
+               entryPtr = Tcl_NextHashEntry(&search)) {
+           children[i] = Tcl_GetHashValue(entryPtr);
+           children[i]->refCount++;
+           i++;
+       }
+       for (i = 0 ; i < length ; i++) {
+           Tcl_DeleteNamespace((Tcl_Namespace *) children[i]);
+           TclNsDecrRefCount(children[i]);
+       }
+       TclStackFree((Tcl_Interp *) iPtr, children);
     }
 #else
     if (nsPtr->childTablePtr != NULL) {
-       for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search);
-               entryPtr != NULL;
-               entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr,&search)) {
-           childNsPtr = Tcl_GetHashValue(entryPtr);
-           Tcl_DeleteNamespace(childNsPtr);
+       while (nsPtr->childTablePtr->numEntries > 0) {
+           int length = nsPtr->childTablePtr->numEntries;
+           Namespace **children = TclStackAlloc((Tcl_Interp *) iPtr,
+                   sizeof(Namespace *) * length);
+
+           i = 0;
+           for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search);
+                   entryPtr != NULL;
+                   entryPtr = Tcl_NextHashEntry(&search)) {
+               children[i] = Tcl_GetHashValue(entryPtr);
+               children[i]->refCount++;
+               i++;
+           }
+           for (i = 0 ; i < length ; i++) {
+               Tcl_DeleteNamespace((Tcl_Namespace *) children[i]);
+               TclNsDecrRefCount(children[i]);
+           }
+           TclStackFree((Tcl_Interp *) iPtr, children);
        }
     }
 #endif
@@ -3312,14 +3354,7 @@ NRNamespaceEvalCmd(
     (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
            namespacePtr, /*isProcCallFrame*/ 0);
 
-    if (iPtr->ensembleRewrite.sourceObjs == NULL) {
-       framePtr->objc = objc;
-       framePtr->objv = objv;
-    } else {
-       framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
-               - iPtr->ensembleRewrite.numInsertedObjs;
-       framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
-    }
+    framePtr->objv = TclFetchEnsembleRoot(interp, objv, objc, &framePtr->objc);
 
     if (objc == 3) {
        /*
@@ -3726,7 +3761,6 @@ NRNamespaceInscopeCmd(
 {
     Tcl_Namespace *namespacePtr;
     CallFrame *framePtr, **framePtrPtr;
-    register Interp *iPtr = (Interp *) interp;
     int i;
     Tcl_Obj *cmdObjPtr;
 
@@ -3752,14 +3786,7 @@ NRNamespaceInscopeCmd(
     (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
            namespacePtr, /*isProcCallFrame*/ 0);
 
-    if (iPtr->ensembleRewrite.sourceObjs == NULL) {
-       framePtr->objc = objc;
-       framePtr->objv = objv;
-    } else {
-       framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
-               - iPtr->ensembleRewrite.numInsertedObjs;
-       framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
-    }
+    framePtr->objv = TclFetchEnsembleRoot(interp, objv, objc, &framePtr->objc);
 
     /*
      * Execute the command. If there is just one argument, just treat it as a
@@ -4511,8 +4538,8 @@ NamespaceUpvarCmd(
        savedNsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
        iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
        otherPtr = TclObjLookupVarEx(interp, objv[0], NULL,
-               (TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
-               /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+               (TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
+               "access", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
        iPtr->varFramePtr->nsPtr = (Namespace *) savedNsPtr;
        if (otherPtr == NULL) {
            return TCL_ERROR;
index 9df5029..ec666ee 100644 (file)
@@ -68,12 +68,9 @@ static int           CloneObjectMethod(Tcl_Interp *interp, Object *oPtr,
 static void            DeletedDefineNamespace(ClientData clientData);
 static void            DeletedObjdefNamespace(ClientData clientData);
 static void            DeletedHelpersNamespace(ClientData clientData);
-static int             FinalizeAlloc(ClientData data[],
-                           Tcl_Interp *interp, int result);
-static int             FinalizeNext(ClientData data[],
-                           Tcl_Interp *interp, int result);
-static int             FinalizeObjectCall(ClientData data[],
-                           Tcl_Interp *interp, int result);
+static Tcl_NRPostProc  FinalizeAlloc;
+static Tcl_NRPostProc  FinalizeNext;
+static Tcl_NRPostProc  FinalizeObjectCall;
 static int             InitFoundation(Tcl_Interp *interp);
 static void            KillFoundation(ClientData clientData,
                            Tcl_Interp *interp);
@@ -1687,7 +1684,7 @@ Tcl_NewObjectInstance(
                TclOOGetCallContext(oPtr, NULL, CONSTRUCTOR, NULL);
 
        if (contextPtr != NULL) {
-           int result;
+           int isRoot, result;
            Tcl_InterpState state;
 
            state = Tcl_SaveInterpState(interp, TCL_OK);
@@ -1698,13 +1695,14 @@ Tcl_NewObjectInstance(
             * Adjust the ensmble tracking record if necessary. [Bug 3514761]
             */
 
-           if (((Interp*) interp)->ensembleRewrite.sourceObjs) {
-               ((Interp*) interp)->ensembleRewrite.numInsertedObjs += skip-1;
-               ((Interp*) interp)->ensembleRewrite.numRemovedObjs += skip-1;
-           }
+           isRoot = TclInitRewriteEnsemble(interp, skip, skip, objv);
            result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr,
                    objc, objv);
 
+           if (isRoot) {
+               TclResetRewriteEnsemble(interp, 1);
+           }
+
            /*
             * It's an error if the object was whacked in the constructor.
             * Force this if it isn't already an error (don't want to lose
@@ -1827,9 +1825,8 @@ TclNRNewObjectInstance(
      * Adjust the ensmble tracking record if necessary. [Bug 3514761]
      */
 
-    if (((Interp *) interp)->ensembleRewrite.sourceObjs) {
-       ((Interp *) interp)->ensembleRewrite.numInsertedObjs += skip - 1;
-       ((Interp *) interp)->ensembleRewrite.numRemovedObjs += skip - 1;
+    if (TclInitRewriteEnsemble(interp, skip, skip, objv)) {
+       TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
     }
 
     /*
index 696908a..46f01fb 100644 (file)
@@ -24,7 +24,7 @@
  * win/tclooConfig.sh
  */
 
-#define TCLOO_VERSION "1.0.4"
+#define TCLOO_VERSION "1.0.5"
 #define TCLOO_PATCHLEVEL TCLOO_VERSION
 
 #include "tcl.h"
index facf90d..1797760 100644 (file)
@@ -70,15 +70,12 @@ static void         AddSimpleClassChainToCallContext(Class *classPtr,
                            Class *const filterDecl);
 static int             CmpStr(const void *ptr1, const void *ptr2);
 static void            DupMethodNameRep(Tcl_Obj *srcPtr, Tcl_Obj *dstPtr);
-static int             FinalizeMethodRefs(ClientData data[],
-                           Tcl_Interp *interp, int result);
+static Tcl_NRPostProc  FinalizeMethodRefs;
 static void            FreeMethodNameRep(Tcl_Obj *objPtr);
 static inline int      IsStillValid(CallChain *callPtr, Object *oPtr,
                            int flags, int reuseMask);
-static int             ResetFilterFlags(ClientData data[],
-                           Tcl_Interp *interp, int result);
-static int             SetFilterFlags(ClientData data[],
-                           Tcl_Interp *interp, int result);
+static Tcl_NRPostProc  ResetFilterFlags;
+static Tcl_NRPostProc  SetFilterFlags;
 static inline void     StashCallChain(Tcl_Obj *objPtr, CallChain *callPtr);
 
 /*
index c880754..8747ff5 100644 (file)
@@ -847,9 +847,8 @@ TclOODefineObjCmd(
        TclDecrRefCount(objNameObj);
     } else {
        Tcl_Obj *objPtr, *obj2Ptr, **objs;
-       Interp *iPtr = (Interp *) interp;
        Tcl_Command cmd;
-       int dummy;
+       int isRoot, dummy;
 
        /*
         * More than one argument: fire them through the ensemble processing
@@ -861,18 +860,7 @@ TclOODefineObjCmd(
         * the moment. Ugly!
         */
 
-       if (iPtr->ensembleRewrite.sourceObjs == NULL) {
-           iPtr->ensembleRewrite.sourceObjs = objv;
-           iPtr->ensembleRewrite.numRemovedObjs = 3;
-           iPtr->ensembleRewrite.numInsertedObjs = 1;
-       } else {
-           int ni = iPtr->ensembleRewrite.numInsertedObjs;
-           if (ni < 3) {
-               iPtr->ensembleRewrite.numRemovedObjs += 3 - ni;
-           } else {
-               iPtr->ensembleRewrite.numInsertedObjs -= 2;
-           }
-       }
+       isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
 
        /*
         * Build the list of arguments using a Tcl_Obj as a workspace. See
@@ -894,6 +882,9 @@ TclOODefineObjCmd(
        Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
 
        result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
+       if (isRoot) {
+           TclResetRewriteEnsemble(interp, 1);
+       }
        Tcl_DecrRefCount(objPtr);
     }
     DelRef(oPtr);
@@ -927,7 +918,7 @@ TclOOObjDefObjCmd(
     Tcl_Obj *const *objv)
 {
     Foundation *fPtr = TclOOGetFoundation(interp);
-    int result;
+    int isRoot, result;
     Object *oPtr;
 
     if (objc < 3) {
@@ -962,7 +953,6 @@ TclOOObjDefObjCmd(
        TclDecrRefCount(objNameObj);
     } else {
        Tcl_Obj *objPtr, *obj2Ptr, **objs;
-       Interp *iPtr = (Interp *) interp;
        Tcl_Command cmd;
        int dummy;
 
@@ -976,18 +966,7 @@ TclOOObjDefObjCmd(
         * the moment. Ugly!
         */
 
-       if (iPtr->ensembleRewrite.sourceObjs == NULL) {
-           iPtr->ensembleRewrite.sourceObjs = objv;
-           iPtr->ensembleRewrite.numRemovedObjs = 3;
-           iPtr->ensembleRewrite.numInsertedObjs = 1;
-       } else {
-           int ni = iPtr->ensembleRewrite.numInsertedObjs;
-           if (ni < 3) {
-               iPtr->ensembleRewrite.numRemovedObjs += 3 - ni;
-           } else {
-               iPtr->ensembleRewrite.numInsertedObjs -= 2;
-           }
-       }
+       isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
 
        /*
         * Build the list of arguments using a Tcl_Obj as a workspace. See
@@ -1009,6 +988,10 @@ TclOOObjDefObjCmd(
        Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
 
        result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
+
+       if (isRoot) {
+           TclResetRewriteEnsemble(interp, 1);
+       }
        Tcl_DecrRefCount(objPtr);
     }
     DelRef(oPtr);
@@ -1077,9 +1060,8 @@ TclOODefineSelfObjCmd(
        TclDecrRefCount(objNameObj);
     } else {
        Tcl_Obj *objPtr, *obj2Ptr, **objs;
-       Interp *iPtr = (Interp *) interp;
        Tcl_Command cmd;
-       int dummy;
+       int isRoot, dummy;
 
        /*
         * More than one argument: fire them through the ensemble processing
@@ -1091,18 +1073,7 @@ TclOODefineSelfObjCmd(
         * the moment. Ugly!
         */
 
-       if (iPtr->ensembleRewrite.sourceObjs == NULL) {
-           iPtr->ensembleRewrite.sourceObjs = objv;
-           iPtr->ensembleRewrite.numRemovedObjs = 2;
-           iPtr->ensembleRewrite.numInsertedObjs = 1;
-       } else {
-           int ni = iPtr->ensembleRewrite.numInsertedObjs;
-           if (ni < 2) {
-               iPtr->ensembleRewrite.numRemovedObjs += 2 - ni;
-           } else {
-               iPtr->ensembleRewrite.numInsertedObjs -= 1;
-           }
-       }
+       isRoot = TclInitRewriteEnsemble(interp, 2, 1, objv);
 
        /*
         * Build the list of arguments using a Tcl_Obj as a workspace. See
@@ -1124,6 +1095,9 @@ TclOODefineSelfObjCmd(
        Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
 
        result = Tcl_EvalObjv(interp, objc-1, objs, TCL_EVAL_INVOKE);
+       if (isRoot) {
+           TclResetRewriteEnsemble(interp, 1);
+       }
        Tcl_DecrRefCount(objPtr);
     }
     DelRef(oPtr);
index 34fa108..99a8bfc 100644 (file)
@@ -70,10 +70,8 @@ static Tcl_Obj **    InitEnsembleRewrite(Tcl_Interp *interp, int objc,
 static int             InvokeProcedureMethod(ClientData clientData,
                            Tcl_Interp *interp, Tcl_ObjectContext context,
                            int objc, Tcl_Obj *const *objv);
-static int             FinalizeForwardCall(ClientData data[], Tcl_Interp *interp,
-                           int result);
-static int             FinalizePMCall(ClientData data[], Tcl_Interp *interp,
-                           int result);
+static Tcl_NRPostProc  FinalizeForwardCall;
+static Tcl_NRPostProc  FinalizePMCall;
 static int             PushMethodCallFrame(Tcl_Interp *interp,
                            CallContext *contextPtr, ProcedureMethod *pmPtr,
                            int objc, Tcl_Obj *const *objv,
@@ -1458,6 +1456,11 @@ InvokeForwardMethod(
     argObjs = InitEnsembleRewrite(interp, objc, objv, skip,
            numPrefixes, prefixObjs, &len);
     Tcl_NRAddCallback(interp, FinalizeForwardCall, argObjs, NULL, NULL, NULL);
+    /*
+     * NOTE: The combination of direct set of iPtr->lookupNsPtr and the use
+     * of the TCL_EVAL_NOERR flag results in an evaluation configuration
+     * very much like TCL_EVAL_INVOKE.
+     */
     ((Interp *)interp)->lookupNsPtr
            = (Namespace *) contextPtr->oPtr->namespacePtr;
     return TclNREvalObjv(interp, len, argObjs, TCL_EVAL_NOERR, NULL);
@@ -1594,12 +1597,9 @@ InitEnsembleRewrite(
     int *lengthPtr)            /* Where to write the resulting length of the
                                 * array of rewritten arguments. */
 {
-    Interp *iPtr = (Interp *) interp;
-    int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
-    Tcl_Obj **argObjs;
     unsigned len = rewriteLength + objc - toRewrite;
+    Tcl_Obj **argObjs = TclStackAlloc(interp, sizeof(Tcl_Obj *) * len);
 
-    argObjs = TclStackAlloc(interp, sizeof(Tcl_Obj *) * len);
     memcpy(argObjs, rewriteObjs, rewriteLength * sizeof(Tcl_Obj *));
     memcpy(argObjs + rewriteLength, objv + toRewrite,
            sizeof(Tcl_Obj *) * (objc - toRewrite));
@@ -1613,22 +1613,9 @@ InitEnsembleRewrite(
      * (and unavoidably).
      */
 
-    if (isRootEnsemble) {
-       iPtr->ensembleRewrite.sourceObjs = objv;
-       iPtr->ensembleRewrite.numRemovedObjs = toRewrite;
-       iPtr->ensembleRewrite.numInsertedObjs = rewriteLength;
-    } else {
-       int numIns = iPtr->ensembleRewrite.numInsertedObjs;
-
-       if (numIns < toRewrite) {
-           iPtr->ensembleRewrite.numRemovedObjs += toRewrite - numIns;
-           iPtr->ensembleRewrite.numInsertedObjs += rewriteLength - 1;
-       } else {
-           iPtr->ensembleRewrite.numInsertedObjs +=
-                   rewriteLength - toRewrite;
-       }
+    if (TclInitRewriteEnsemble(interp, toRewrite, rewriteLength, objv)) {
+       TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
     }
-
     *lengthPtr = len;
     return argObjs;
 }
index c641152..628c3a7 100644 (file)
@@ -320,7 +320,7 @@ const Tcl_HashKeyType tclObjHashKeyType = {
  * does allow them to delete a command when references to it are gone, which
  * is fragile but useful given their somewhat-OO style. Because of this, this
  * structure MUST NOT be const so that the C compiler puts the data in
- * writable memory. [Bug 2558422]
+ * writable memory. [Bug 2558422] [Bug 07d13d99b0a9]
  * TODO: Provide a better API for those extensions so that they can coexist...
  */
 
@@ -4176,7 +4176,8 @@ Tcl_GetCommandFromObj(
      * had is invalid one way or another.
      */
 
-    if (SetCmdNameFromAny(interp, objPtr) != TCL_OK) {
+    /* See [] why we cannot call SetCmdNameFromAny() directly here. */
+    if (tclCmdNameType.setFromAnyProc(interp, objPtr) != TCL_OK) {
         return NULL;
     }
     resPtr = objPtr->internalRep.twoPtrValue.ptr1;
index 99d576d..c2643bf 100644 (file)
@@ -869,12 +869,16 @@ TclJoinPath(
         * object which can be normalized more efficiently. Currently we only
         * use the special case when we have exactly two elements, but we
         * could expand that in the future.
+         *
+         * Bugfix [a47641a0]. TclNewFSPathObj requires first argument
+         * to be an absolute path. Added a check for that elt is absolute.
         */
 
        if ((i == (elements-2)) && (i == 0)
-               && (elt->typePtr == &tclFsPathType)
-               && !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))) {
-           Tcl_Obj *tailObj = objv[i+1];
+                && (elt->typePtr == &tclFsPathType)
+               && !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))
+                && TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
+            Tcl_Obj *tailObj = objv[i+1];
 
            type = TclGetPathType(tailObj, NULL, NULL, NULL);
            if (type == TCL_PATH_RELATIVE) {
index ac65bde..ae9e7cd 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 typedef struct {
-    int isRootEnsemble;
     Command cmd;
     ExtraFrameInfo efi;
 } ApplyExtraData;
@@ -69,9 +68,8 @@ const Tcl_ObjType tclProcBodyType = {
 };
 
 /*
- * The [upvar]/[uplevel] level reference type. Uses the twoPtrValue field,
- * encoding the type of level reference in ptr and the actual parsed out
- * offset in ptr2.
+ * The [upvar]/[uplevel] level reference type. Uses the longValue field
+ * to remember the integer value of a parsed #<integer> format.
  *
  * Uses the default behaviour throughout, and never disposes of the string
  * rep; it's just a cache type.
@@ -785,7 +783,7 @@ TclGetFrame(
  * Results:
  *     The return value is -1 if an error occurred in finding the frame (in
  *     this case an error message is left in the interp's result). 1 is
- *     returned if objPtr was either a number or a number preceded by "#" and
+ *     returned if objPtr was either an int or an int preceded by "#" and
  *     it specified a valid frame. 0 is returned if objPtr isn't one of the
  *     two things above (in this case, the lookup acts as if objPtr were
  *     "1"). The variable pointed to by framePtrPtr is filled in with the
@@ -807,97 +805,71 @@ TclObjGetFrame(
 {
     register Interp *iPtr = (Interp *) interp;
     int curLevel, level, result;
-    CallFrame *framePtr;
-    const char *name;
+    const char *name = NULL;
 
     /*
      * Parse object to figure out which level number to go to.
      */
 
-    result = 1;
+    result = 0;
     curLevel = iPtr->varFramePtr->level;
-    if (objPtr == NULL) {
-       name = "1";
-       goto haveLevel1;
-    }
-
-    name = TclGetString(objPtr);
-    if (objPtr->typePtr == &levelReferenceType) {
-       if (objPtr->internalRep.twoPtrValue.ptr1) {
-           level = curLevel - PTR2INT(objPtr->internalRep.twoPtrValue.ptr2);
-       } else {
-           level = PTR2INT(objPtr->internalRep.twoPtrValue.ptr2);
-       }
-       if (level < 0) {
-           goto levelError;
-       }
-       /* TODO: Consider skipping the typePtr checks */
-    } else if (objPtr->typePtr == &tclIntType
-#ifndef TCL_WIDE_INT_IS_LONG
-           || objPtr->typePtr == &tclWideIntType
-#endif
-           ) {
-       if (TclGetIntFromObj(NULL, objPtr, &level) != TCL_OK || level < 0) {
-           goto levelError;
-       }
-       level = curLevel - level;
-    } else if (*name == '#') {
-       if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
-           goto levelError;
-       }
-
-       /*
-        * Cache for future reference.
-        */
-
-       TclFreeIntRep(objPtr);
-       objPtr->typePtr = &levelReferenceType;
-       objPtr->internalRep.twoPtrValue.ptr1 = (void *) 0;
-       objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(level);
-    } else if (isdigit(UCHAR(*name))) { /* INTL: digit */
-       if (Tcl_GetInt(interp, name, &level) != TCL_OK) {
-           return -1;
-       }
 
-       /*
-        * Cache for future reference.
-        */
+    /*
+     * Check for integer first, since that has potential to spare us
+     * a generation of a stringrep.
+     */
 
-       TclFreeIntRep(objPtr);
-       objPtr->typePtr = &levelReferenceType;
-       objPtr->internalRep.twoPtrValue.ptr1 = (void *) 1;
-       objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(level);
+    if (objPtr == NULL) {
+       /* Do nothing */
+    } else if (TCL_OK == Tcl_GetIntFromObj(NULL, objPtr, &level)
+           && (level >= 0)) {
        level = curLevel - level;
+       result = 1;
+    } else if (objPtr->typePtr == &levelReferenceType) {
+       level = (int) objPtr->internalRep.longValue;
+       result = 1;
     } else {
-       /*
-        * Don't cache as the object *isn't* a level reference (might even be
-        * NULL...)
-        */
+       name = TclGetString(objPtr);
+       if (name[0] == '#') {
+           if (TCL_OK == Tcl_GetInt(NULL, name+1, &level) && level >= 0) {
+               TclFreeIntRep(objPtr);
+               objPtr->typePtr = &levelReferenceType;
+               objPtr->internalRep.longValue = level;
+               result = 1;
+           } else {
+               result = -1;
+           }
+       } else if (isdigit(UCHAR(name[0]))) { /* INTL: digit */
+           /*
+            * If this were an integer, we'd have succeeded already.
+            * Docs say we have to treat this as a 'bad level'  error.
+            */
+           result = -1;
+       }
+    }
 
-    haveLevel1:
+    if (result == 0) {
        level = curLevel - 1;
-       result = 0;
+       name = "1";
     }
-
-    /*
-     * Figure out which frame to use, and return it to the caller.
-     */
-
-    for (framePtr = iPtr->varFramePtr; framePtr != NULL;
-           framePtr = framePtr->callerVarPtr) {
-       if (framePtr->level == level) {
-           break;
+    if (result != -1) {
+       if (level >= 0) {
+           CallFrame *framePtr;
+           for (framePtr = iPtr->varFramePtr; framePtr != NULL;
+                   framePtr = framePtr->callerVarPtr) {
+               if (framePtr->level == level) {
+                   *framePtrPtr = framePtr;
+                   return result;
+               }
+           }
+       }
+       if (name == NULL) {
+           name = TclGetString(objPtr);
        }
     }
-    if (framePtr == NULL) {
-       goto levelError;
-    }
-    *framePtrPtr = framePtr;
-    return result;
 
-  levelError:
     Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name));
-    Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL);
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL", name, NULL);
     return -1;
 }
 \f
@@ -1115,12 +1087,10 @@ ProcWrongNumArgs(
     if (framePtr->isProcCallFrame & FRAME_IS_LAMBDA) {
        desiredObjs[0] = Tcl_NewStringObj("lambdaExpr", -1);
     } else {
-       ((Interp *) interp)->ensembleRewrite.numInsertedObjs -= skip - 1;
-
 #ifdef AVOID_HACKS_FOR_ITCL
        desiredObjs[0] = framePtr->objv[skip-1];
 #else
-       desiredObjs[0] = Tcl_NewListObj(skip, framePtr->objv);
+       desiredObjs[0] = Tcl_NewListObj(1, framePtr->objv + skip - 1);
 #endif /* AVOID_HACKS_FOR_ITCL */
     }
     Tcl_IncrRefCount(desiredObjs[0]);
@@ -1555,6 +1525,10 @@ InitArgsAndLocals(
      */
 
   incorrectArgs:
+    if ((skip != 1) &&
+           TclInitRewriteEnsemble(interp, skip-1, 0, framePtr->objv)) {
+       TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+    }
     memset(varPtr, 0,
            ((framePtr->compiledLocals + localCt)-varPtr) * sizeof(Var));
     return ProcWrongNumArgs(interp, skip);
@@ -2661,7 +2635,7 @@ TclNRApplyObjCmd(
     Interp *iPtr = (Interp *) interp;
     Proc *procPtr = NULL;
     Tcl_Obj *lambdaPtr, *nsObjPtr;
-    int result, isRootEnsemble;
+    int result;
     Tcl_Namespace *nsPtr;
     ApplyExtraData *extraPtr;
 
@@ -2744,16 +2718,6 @@ TclNRApplyObjCmd(
     extraPtr->efi.fields[0].clientData = lambdaPtr;
     extraPtr->cmd.clientData = &extraPtr->efi;
 
-    isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
-    if (isRootEnsemble) {
-       iPtr->ensembleRewrite.sourceObjs = objv;
-       iPtr->ensembleRewrite.numRemovedObjs = 1;
-       iPtr->ensembleRewrite.numInsertedObjs = 0;
-    } else {
-       iPtr->ensembleRewrite.numInsertedObjs -= 1;
-    }
-    extraPtr->isRootEnsemble = isRootEnsemble;
-
     result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1);
     if (result == TCL_OK) {
        TclNRAddCallback(interp, ApplyNR2, extraPtr, NULL, NULL, NULL);
@@ -2770,10 +2734,6 @@ ApplyNR2(
 {
     ApplyExtraData *extraPtr = data[0];
 
-    if (extraPtr->isRootEnsemble) {
-       ((Interp *) interp)->ensembleRewrite.sourceObjs = NULL;
-    }
-
     TclStackFree(interp, extraPtr);
     return result;
 }
index 8d70d20..11a57e9 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "tclInt.h"
 #include "tommath.h"
+#include "tclStringRep.h"
 
 /*
  * Set COMPAT to 1 to restore the shimmering patterns to those of Tcl 8.5.
@@ -89,60 +90,6 @@ const Tcl_ObjType tclStringType = {
     UpdateStringOfString,      /* updateStringProc */
     SetStringFromAny           /* setFromAnyProc */
 };
-
-/*
- * The following structure is the internal rep for a String object. It keeps
- * track of how much memory has been used and how much has been allocated for
- * the Unicode and UTF string to enable growing and shrinking of the UTF and
- * Unicode reps of the String object with fewer mallocs. To optimize string
- * length and indexing operations, this structure also stores the number of
- * characters (same of UTF and Unicode!) once that value has been computed.
- *
- * Under normal configurations, what Tcl calls "Unicode" is actually UTF-16
- * restricted to the Basic Multilingual Plane (i.e. U+00000 to U+0FFFF). This
- * can be officially modified by altering the definition of Tcl_UniChar in
- * tcl.h, but do not do that unless you are sure what you're doing!
- */
-
-typedef struct String {
-    int numChars;              /* The number of chars in the string. -1 means
-                                * this value has not been calculated. >= 0
-                                * means that there is a valid Unicode rep, or
-                                * that the number of UTF bytes == the number
-                                * of chars. */
-    int allocated;             /* The amount of space actually allocated for
-                                * the UTF string (minus 1 byte for the
-                                * termination char). */
-    int maxChars;              /* Max number of chars that can fit in the
-                                * space allocated for the unicode array. */
-    int hasUnicode;            /* Boolean determining whether the string has
-                                * a Unicode representation. */
-    Tcl_UniChar unicode[1];    /* The array of Unicode chars. The actual size
-                                * of this field depends on the 'maxChars'
-                                * field above. */
-} String;
-
-#define STRING_MAXCHARS \
-       (int)(((size_t)UINT_MAX - sizeof(String))/sizeof(Tcl_UniChar))
-#define STRING_SIZE(numChars) \
-       (sizeof(String) + ((numChars) * sizeof(Tcl_UniChar)))
-#define stringCheckLimits(numChars) \
-    if ((numChars) < 0 || (numChars) > STRING_MAXCHARS) { \
-       Tcl_Panic("max length for a Tcl unicode value (%d chars) exceeded", \
-               STRING_MAXCHARS); \
-    }
-#define stringAttemptAlloc(numChars) \
-       (String *) attemptckalloc((unsigned) STRING_SIZE(numChars) )
-#define stringAlloc(numChars) \
-       (String *) ckalloc((unsigned) STRING_SIZE(numChars) )
-#define stringRealloc(ptr, numChars) \
-    (String *) ckrealloc((ptr), (unsigned) STRING_SIZE(numChars) )
-#define stringAttemptRealloc(ptr, numChars) \
-    (String *) attemptckrealloc((ptr), (unsigned) STRING_SIZE(numChars) )
-#define GET_STRING(objPtr) \
-       ((String *) (objPtr)->internalRep.twoPtrValue.ptr1)
-#define SET_STRING(objPtr, stringPtr) \
-       ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr))
 \f
 /*
  * TCL STRING GROWTH ALGORITHM
diff --git a/generic/tclStringRep.h b/generic/tclStringRep.h
new file mode 100644 (file)
index 0000000..227e6bc
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * tclStringRep.h --
+ *
+ *     This file contains the definition of the Unicode string internal
+ *     representation and macros to access it.
+ *
+ *     A Unicode string is an internationalized string. Conceptually, a
+ *     Unicode string is an array of 16-bit quantities organized as a
+ *     sequence of properly formed UTF-8 characters. There is a one-to-one
+ *     map between Unicode and UTF characters. Because Unicode characters
+ *     have a fixed width, operations such as indexing operate on Unicode
+ *     data. The String object is optimized for the case where each UTF char
+ *     in a string is only one byte. In this case, we store the value of
+ *     numChars, but we don't store the Unicode data (unless Tcl_GetUnicode
+ *     is explicitly called).
+ *
+ *     The String object type stores one or both formats. The default
+ *     behavior is to store UTF. Once Unicode is calculated by a function, it
+ *     is stored in the internal rep for future access (without an additional
+ *     O(n) cost).
+ *
+ *     To allow many appends to be done to an object without constantly
+ *     reallocating the space for the string or Unicode representation, we
+ *     allocate double the space for the string or Unicode and use the
+ *     internal representation to keep track of how much space is used vs.
+ *     allocated.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 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.
+ */
+\f
+/*
+ * The following structure is the internal rep for a String object. It keeps
+ * track of how much memory has been used and how much has been allocated for
+ * the Unicode and UTF string to enable growing and shrinking of the UTF and
+ * Unicode reps of the String object with fewer mallocs. To optimize string
+ * length and indexing operations, this structure also stores the number of
+ * characters (same of UTF and Unicode!) once that value has been computed.
+ *
+ * Under normal configurations, what Tcl calls "Unicode" is actually UTF-16
+ * restricted to the Basic Multilingual Plane (i.e. U+00000 to U+0FFFF). This
+ * can be officially modified by altering the definition of Tcl_UniChar in
+ * tcl.h, but do not do that unless you are sure what you're doing!
+ */
+
+typedef struct String {
+    int numChars;              /* The number of chars in the string. -1 means
+                                * this value has not been calculated. >= 0
+                                * means that there is a valid Unicode rep, or
+                                * that the number of UTF bytes == the number
+                                * of chars. */
+    int allocated;             /* The amount of space actually allocated for
+                                * the UTF string (minus 1 byte for the
+                                * termination char). */
+    int maxChars;              /* Max number of chars that can fit in the
+                                * space allocated for the unicode array. */
+    int hasUnicode;            /* Boolean determining whether the string has
+                                * a Unicode representation. */
+    Tcl_UniChar unicode[1];    /* The array of Unicode chars. The actual size
+                                * of this field depends on the 'maxChars'
+                                * field above. */
+} String;
+
+#define STRING_MAXCHARS \
+    (int)(((size_t)UINT_MAX - sizeof(String))/sizeof(Tcl_UniChar))
+#define STRING_SIZE(numChars) \
+    (sizeof(String) + ((numChars) * sizeof(Tcl_UniChar)))
+#define stringCheckLimits(numChars) \
+    do {                                                               \
+       if ((numChars) < 0 || (numChars) > STRING_MAXCHARS) {           \
+           Tcl_Panic("max length for a Tcl unicode value (%d chars) exceeded", \
+                     STRING_MAXCHARS);                                 \
+       }                                                               \
+    } while (0)
+#define stringAttemptAlloc(numChars) \
+    (String *) attemptckalloc((unsigned) STRING_SIZE(numChars))
+#define stringAlloc(numChars) \
+    (String *) ckalloc((unsigned) STRING_SIZE(numChars))
+#define stringRealloc(ptr, numChars) \
+    (String *) ckrealloc((ptr), (unsigned) STRING_SIZE(numChars))
+#define stringAttemptRealloc(ptr, numChars) \
+    (String *) attemptckrealloc((ptr), (unsigned) STRING_SIZE(numChars))
+#define GET_STRING(objPtr) \
+    ((String *) (objPtr)->internalRep.twoPtrValue.ptr1)
+#define SET_STRING(objPtr, stringPtr) \
+    ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr))
+\f
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
index 9794f59..e33d263 100644 (file)
@@ -413,8 +413,7 @@ static int          TestHashSystemHashCmd(ClientData clientData,
                            Tcl_Interp *interp, int objc,
                            Tcl_Obj *const objv[]);
 
-static int              NREUnwind_callback(ClientData data[], Tcl_Interp *interp,
-                            int result);
+static Tcl_NRPostProc  NREUnwind_callback;
 static int             TestNREUnwind(ClientData clientData,
                            Tcl_Interp *interp, int objc,
                            Tcl_Obj *const objv[]);
@@ -6891,7 +6890,7 @@ TestNREUnwind(
      * Insure that callbacks effectively run at the proper level during the
      * unwinding of the NRE stack.
      */
-    
+
     Tcl_NRAddCallback(interp, NREUnwind_callback, INT2PTR(-1), INT2PTR(-1),
             INT2PTR(-1), NULL);
     return TCL_OK;
index f36b07f..a637498 100644 (file)
@@ -19,6 +19,7 @@
 #endif
 #include "tclInt.h"
 #include "tommath.h"
+#include "tclStringRep.h"
 
 
 /*
@@ -46,13 +47,6 @@ static int           TestobjCmd(ClientData dummy, Tcl_Interp *interp,
                            int objc, Tcl_Obj *const objv[]);
 static int             TeststringobjCmd(ClientData dummy, Tcl_Interp *interp,
                            int objc, Tcl_Obj *const objv[]);
-
-typedef struct TestString {
-    int numChars;
-    int allocated;
-    int maxChars;
-    Tcl_UniChar unicode[2];
-} TestString;
 \f
 #define VARPTR_KEY "TCLOBJTEST_VARPTR"
 #define NUMBER_OF_OBJECT_VARS 20
@@ -1141,7 +1135,7 @@ TeststringobjCmd(
     int varIndex, option, i, length;
 #define MAX_STRINGS 11
     const char *index, *string, *strings[MAX_STRINGS+1];
-    TestString *strPtr;
+    String *strPtr;
     Tcl_Obj **varPtr;
     static const char *const options[] = {
        "append", "appendstrings", "get", "get2", "length", "length2",
index 75f8a15..9c66313 100644 (file)
@@ -834,7 +834,7 @@ ThreadSend(
 
     if (threadId == Tcl_GetCurrentThread()) {
        Tcl_MutexUnlock(&threadMutex);
-       return Tcl_EvalEx(interp, script,-1,TCL_EVAL_GLOBAL);   
+       return Tcl_EvalEx(interp, script,-1,TCL_EVAL_GLOBAL);
     }
 
     /*
@@ -1029,7 +1029,7 @@ ThreadEventProc(
        Tcl_Preserve(interp);
        Tcl_ResetResult(interp);
        Tcl_CreateThreadExitHandler(ThreadFreeProc, threadEventPtr->script);
-       code = Tcl_EvalEx(interp, threadEventPtr->script,-1,TCL_EVAL_GLOBAL);   
+       code = Tcl_EvalEx(interp, threadEventPtr->script,-1,TCL_EVAL_GLOBAL);
        Tcl_DeleteThreadExitHandler(ThreadFreeProc, threadEventPtr->script);
        if (code != TCL_OK) {
            errorCode = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
index 1ca119d..d8b317a 100644 (file)
@@ -29,36 +29,36 @@ static const unsigned short pageMap[] = {
     832, 864, 896, 928, 960, 992, 224, 1024, 224, 1056, 224, 224, 1088,
     1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1344, 1344,
     1440, 1472, 1504, 1536, 1568, 1344, 1344, 1600, 1632, 1664, 1696, 1728,
-    1760, 1792, 1792, 1824, 1792, 1856, 1888, 1920, 1952, 1984, 2016, 2048,
-    2080, 2112, 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2400, 2432,
-    2464, 2496, 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816,
-    2848, 2880, 2784, 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168,
-    3200, 1792, 3232, 3264, 3296, 1792, 3328, 3360, 3392, 3424, 3456, 3488,
-    3520, 1792, 1344, 3552, 3584, 3616, 3648, 3680, 3712, 3744, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3776, 1344, 3808, 3840,
-    3872, 1344, 3904, 1344, 3936, 3968, 4000, 4032, 4032, 4064, 4096, 1344,
+    1760, 1792, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, 2048, 2080,
+    2112, 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464,
+    2496, 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, 2848,
+    2880, 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, 3200, 3232,
+    3264, 1792, 3296, 3328, 3360, 1792, 3392, 3424, 3456, 3488, 3520, 3552,
+    3584, 1792, 1344, 3616, 3648, 3680, 3712, 3744, 3776, 3808, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3840, 1344, 3872, 3904,
+    3936, 1344, 3968, 1344, 4000, 4032, 4064, 4096, 4096, 4128, 4160, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 4128, 4160, 1344, 1344, 4192, 4224, 4256,
-    4288, 4320, 1344, 4352, 4384, 4416, 4448, 1344, 4480, 4512, 1344, 4544,
-    1344, 4576, 4608, 4640, 4672, 4704, 1344, 4736, 4768, 4800, 4832, 1344,
-    4864, 4896, 4928, 4960, 1792, 1792, 4992, 5024, 5056, 5088, 5120, 5152,
-    1344, 5184, 1344, 5216, 5248, 5280, 1792, 1792, 5312, 5344, 5376, 5408,
-    5440, 5472, 5504, 5440, 704, 5536, 224, 224, 224, 224, 5568, 224, 224,
-    224, 5600, 5632, 5664, 5696, 5728, 5760, 5792, 5824, 5856, 5888, 5920,
-    5952, 5984, 6016, 6048, 6080, 6112, 6144, 6176, 6208, 6240, 6272, 6304,
-    6336, 6368, 6368, 6368, 6368, 6368, 6368, 6368, 6368, 6400, 6432, 4800,
-    6464, 6496, 6528, 6560, 6592, 4800, 6624, 6656, 6688, 6720, 6752, 6784,
-    6816, 4800, 4800, 4800, 4800, 4800, 6848, 6880, 6912, 4800, 4800, 4800,
-    6944, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 6976, 7008, 4800, 7040,
-    7072, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 6368, 6368, 6368,
-    6368, 7104, 6368, 7136, 7168, 6368, 6368, 6368, 6368, 6368, 6368, 6368,
-    6368, 4800, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488,
-    7520, 224, 224, 224, 7552, 7584, 7616, 1344, 7648, 7680, 7712, 7712,
-    704, 7744, 7776, 7808, 1792, 7840, 4800, 4800, 7872, 4800, 4800, 4800,
-    4800, 4800, 4800, 7904, 7936, 7968, 8000, 3136, 1344, 8032, 4096, 1344,
-    8064, 8096, 8128, 1344, 1344, 8160, 8192, 4800, 8224, 8256, 8288, 8320,
-    4800, 8288, 8352, 4800, 8256, 4800, 4800, 4800, 4800, 4800, 4800, 4800,
-    4800, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 4192, 4224, 1344, 1344, 4256, 4288, 4320,
+    4352, 4384, 1344, 4416, 4448, 4480, 4512, 1344, 4544, 4576, 4608, 4640,
+    1344, 4672, 4704, 4736, 4768, 4800, 1344, 4832, 4864, 4896, 4928, 1344,
+    4960, 4992, 5024, 5056, 1792, 1792, 5088, 5120, 5152, 5184, 5216, 5248,
+    1344, 5280, 1344, 5312, 5344, 5376, 5408, 1792, 5440, 5472, 5504, 5536,
+    5568, 5600, 5632, 5568, 704, 5664, 224, 224, 224, 224, 5696, 224, 224,
+    224, 5728, 5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048,
+    6080, 6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432,
+    6464, 6496, 6496, 6496, 6496, 6496, 6496, 6496, 6496, 6528, 6560, 4896,
+    6592, 6624, 6656, 6688, 6720, 4896, 6752, 6784, 6816, 6848, 6880, 6912,
+    6944, 4896, 4896, 4896, 4896, 4896, 6976, 7008, 7040, 4896, 4896, 4896,
+    7072, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 7104, 7136, 4896, 7168,
+    7200, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 6496, 6496, 6496,
+    6496, 7232, 6496, 7264, 7296, 6496, 6496, 6496, 6496, 6496, 6496, 6496,
+    6496, 4896, 7328, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584, 7616,
+    7648, 224, 224, 224, 7680, 7712, 7744, 1344, 7776, 7808, 7840, 7840,
+    704, 7872, 7904, 7936, 1792, 7968, 4896, 4896, 8000, 4896, 4896, 4896,
+    4896, 4896, 4896, 8032, 8064, 8096, 8128, 3200, 1344, 8160, 4160, 1344,
+    8192, 8224, 8256, 1344, 1344, 8288, 8320, 4896, 8352, 8384, 8416, 8448,
+    4896, 8416, 8480, 4896, 8384, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -75,7 +75,7 @@ static const unsigned short pageMap[] = {
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 4576, 4800, 4800, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 4672, 4896, 4896, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -129,16 +129,16 @@ static const unsigned short pageMap[] = {
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4576,
-    1792, 8384, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4672,
+    1792, 8512, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 8416, 4800, 8448, 5280, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 8480, 8512, 224, 8544, 8576, 1344, 1344, 8608, 8640, 8672, 224,
-    8704, 8736, 8768, 1792, 8800, 8832, 8864, 1344, 8896, 8928, 8960, 8992,
-    9024, 1632, 9056, 9088, 9120, 1888, 9152, 9184, 9216, 1344, 9248, 9280,
-    9312, 1344, 9344, 9376, 9408, 9440, 9472, 9504, 9536, 9568, 9568, 1344,
-    9600, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 8544, 4896, 8576, 5376, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 8608, 8640, 224, 8672, 8704, 1344, 1344, 8736, 8768, 8800, 224,
+    8832, 8864, 8896, 1792, 8928, 8960, 8992, 1344, 9024, 9056, 9088, 9120,
+    9152, 1632, 9184, 9216, 9248, 1920, 9280, 9312, 9344, 1344, 9376, 9408,
+    9440, 1344, 9472, 9504, 9536, 9568, 9600, 9632, 9664, 9696, 9696, 1344,
+    9728, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -167,95 +167,73 @@ static const unsigned short pageMap[] = {
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 9632, 9664, 9696, 9728, 9728, 9728, 9728, 9728, 9728, 9728,
-    9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728,
-    9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728,
-    9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728,
-    9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728,
-    9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760,
-    9760, 9760, 9760, 9760, 9760, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 9792, 1344, 1344, 9824, 1792, 9856, 9888, 9920,
-    1344, 1344, 9952, 9984, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 10016, 10048, 1344, 10080, 1344, 10112, 10144, 10176, 10208,
-    10240, 10272, 1344, 1344, 1344, 10304, 10336, 64, 10368, 10400, 10432,
-    4608, 10464, 10496
+    1344, 1344, 9760, 9792, 9824, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 9920, 1344, 1344, 9952, 1792, 9984, 10016,
+    10048, 1344, 1344, 10080, 10112, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 10144, 10176, 1344, 10208, 1344, 10240, 10272,
+    10304, 10336, 10368, 10400, 1344, 1344, 1344, 10432, 10464, 64, 10496,
+    10528, 10560, 4704, 10592, 10624
 #if TCL_UTF_MAX > 3
-    ,10528, 10560, 10592, 1792, 1344, 1344, 1344, 8192, 10624, 10656, 10688,
-    10720, 10752, 10784, 10816, 10848, 1792, 1792, 1792, 1792, 9120, 1344,
-    10880, 10912, 1344, 10944, 10976, 11008, 11040, 1344, 11072, 1792,
-    11104, 11136, 11168, 1344, 11200, 11232, 1792, 1792, 1344, 11264, 1344,
-    11296, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 7680, 4576, 10112, 1792, 1792, 1792, 1792, 11328,
-    11360, 11392, 11424, 4608, 11456, 1792, 11488, 11520, 11552, 1792,
-    1792, 1344, 11584, 11616, 6688, 11648, 11680, 11712, 11744, 11776,
-    1792, 11808, 11840, 1344, 11872, 11904, 11936, 11968, 12000, 1792,
-    1792, 1344, 1344, 12032, 1792, 12064, 12096, 12128, 12160, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12192, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12224,
-    12256, 12288, 12320, 5120, 12352, 12384, 12416, 12448, 12480, 12512,
-    12544, 5120, 12576, 12608, 12640, 12672, 12704, 1792, 1792, 12736,
-    12768, 12800, 12832, 12864, 2304, 12896, 12928, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1344, 12960, 12992, 1792, 1792, 1792, 1792,
-    1792, 1344, 13024, 13056, 1792, 1344, 13088, 13120, 1792, 1344, 13152,
-    11232, 1792, 13184, 13216, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 13248, 13280, 13312, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 13344,
+    ,10656, 10688, 10720, 1792, 1344, 1344, 1344, 8320, 10752, 10784, 10816,
+    10848, 10880, 10912, 10944, 10976, 1792, 1792, 1792, 1792, 9248, 1344,
+    11008, 11040, 1344, 11072, 11104, 11136, 11168, 1344, 11200, 1792,
+    11232, 11264, 11296, 1344, 11328, 11360, 11392, 11424, 1344, 11456,
+    1344, 11488, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 7808, 4672, 10240, 1792, 1792, 1792, 1792,
+    11520, 11552, 11584, 11616, 4704, 11648, 1792, 11680, 11712, 11744,
+    1792, 1792, 1344, 11776, 11808, 6816, 11840, 11872, 11904, 11936, 11968,
+    1792, 12000, 12032, 1344, 12064, 12096, 12128, 12160, 12192, 1792,
+    1792, 1344, 1344, 12224, 1792, 12256, 12288, 12320, 12352, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12384, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12416,
+    12448, 12480, 12512, 5216, 12544, 12576, 12608, 12640, 12672, 12704,
+    12736, 5216, 12768, 12800, 12832, 12864, 12896, 1792, 1792, 12928,
+    12960, 12992, 13024, 13056, 2336, 13088, 13120, 1792, 1792, 1792, 1792,
+    1344, 13152, 13184, 1792, 1344, 13216, 13248, 1792, 1792, 1792, 1792,
+    1792, 1344, 13280, 13312, 1792, 1344, 13344, 13376, 13408, 1344, 13440,
+    13472, 1792, 13504, 13536, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 13568, 13600, 13632, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 13664,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 13696, 13728, 13760,
+    13792, 13824, 13856, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9824, 1792, 1792, 1792,
-    10688, 10688, 10688, 13376, 1344, 1344, 1344, 1344, 1344, 1344, 13408,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9952, 1792,
+    1792, 1792, 10816, 10816, 10816, 13888, 1344, 1344, 1344, 1344, 1344,
+    1344, 13920, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 13440,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    13472, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1344, 13952, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
@@ -265,14 +243,10 @@ static const unsigned short pageMap[] = {
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    13344, 4608, 13504, 1792, 1792, 10048, 13536, 1344, 13568, 13600, 13632,
-    13664, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1344, 1344, 1344, 13984, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1344, 1344, 13696, 13728, 13760, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
@@ -293,7 +267,31 @@ static const unsigned short pageMap[] = {
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 13664, 4704, 14016, 1792, 1792, 10176, 14048, 1344,
+    14080, 14112, 14144, 14176, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 14208,
+    14240, 14272, 1792, 1792, 14304, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 14336, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 14368, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
@@ -315,19 +313,18 @@ static const unsigned short pageMap[] = {
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 13792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 14400, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344,
-    1344, 1344, 13824, 13856, 13888, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 14432, 14464, 14496,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
@@ -337,40 +334,44 @@ static const unsigned short pageMap[] = {
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 7904,
-    4800, 13920, 4800, 13952, 13984, 14016, 4800, 14048, 4800, 4800, 14080,
-    1792, 1792, 1792, 1792, 1792, 4800, 4800, 14112, 14144, 1792, 1792,
-    1792, 1792, 14176, 14208, 14240, 14272, 14304, 14336, 14368, 14400,
-    14432, 14464, 14496, 14528, 14560, 14176, 14208, 14592, 14272, 14624,
-    14656, 14688, 14400, 14720, 14752, 14784, 14816, 14848, 14880, 14912,
-    14944, 14976, 15008, 15040, 4800, 4800, 4800, 4800, 4800, 4800, 4800,
-    4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 704, 15072, 704,
-    15104, 15136, 15168, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 4896, 4896,
+    4896, 4896, 4896, 4896, 4896, 8032, 4896, 14528, 4896, 14560, 14592,
+    14624, 4896, 14656, 4896, 4896, 14688, 1792, 1792, 1792, 1792, 1792,
+    4896, 4896, 14720, 14752, 1792, 1792, 1792, 1792, 14784, 14816, 14848,
+    14880, 14912, 14944, 14976, 15008, 15040, 15072, 15104, 15136, 15168,
+    14784, 14816, 15200, 14880, 15232, 15264, 15296, 15008, 15328, 15360,
+    15392, 15424, 15456, 15488, 15520, 15552, 15584, 15616, 15648, 4896,
+    4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 4896, 704, 15680, 704, 15712, 15744, 15776, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 15808, 15840, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 15200, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344,
+    1344, 1344, 1344, 15872, 1792, 15904, 15936, 15968, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 15232, 15264, 15296, 15328, 15360, 15392, 1792, 15424,
-    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 4800, 15456, 4800,
-    4800, 7872, 15488, 15520, 7904, 15552, 15584, 4800, 15456, 15616, 1792,
-    1792, 15648, 15680, 15616, 15712, 1792, 1792, 1792, 1792, 1792, 4800,
-    4800, 4800, 4800, 4800, 4800, 4800, 15744, 4800, 4800, 4800, 4800,
-    4800, 4800, 4800, 4800, 4800, 4800, 4800, 7840, 4800, 15776, 4800,
-    4800, 4800, 4800, 4800, 4800, 4800, 4800, 15808, 15840, 4800, 4800,
-    4800, 7872, 4800, 4800, 15872, 1792, 15456, 4800, 15904, 4800, 15936,
-    15968, 1792, 1792, 16000, 1792, 1792, 1792, 16032, 1792, 10784, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 16000,
+    16032, 16064, 16096, 16128, 16160, 1792, 16192, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 4896, 16224, 4896, 4896, 8000, 16256, 16288,
+    8032, 16320, 16352, 4896, 16224, 4896, 16384, 1792, 16416, 16448, 16480,
+    16512, 1792, 1792, 1792, 1792, 1792, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 16544, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 16576, 16608, 4896, 4896, 4896, 8000, 4896, 4896, 16640,
+    1792, 16224, 4896, 16672, 4896, 16704, 16736, 1792, 1792, 16768, 16800,
+    16832, 1792, 16864, 1792, 10912, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -481,8 +482,7 @@ static const unsigned short pageMap[] = {
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 7680, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 7808, 1792, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -493,7 +493,8 @@ static const unsigned short pageMap[] = {
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 11200, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 16896, 1344, 1344,
+    1344, 1344, 1344, 1344, 11328, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -508,7 +509,7 @@ static const unsigned short pageMap[] = {
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
     1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 13792,
+    1344, 1344, 1344, 1344, 1344, 1344, 14400, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
@@ -536,8 +537,8 @@ static const unsigned short pageMap[] = {
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
     1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
-    1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344,
-    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11200
+    1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 11328
 #endif /* TCL_UTF_MAX > 3 */
 };
 
@@ -579,7 +580,7 @@ static const unsigned char groupMap[] = {
     23, 24, 21, 21, 21, 21, 21, 21, 55, 23, 24, 56, 57, 58, 58, 23, 24,
     59, 60, 61, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 62, 63, 64, 65,
     66, 21, 67, 67, 21, 68, 21, 69, 70, 21, 21, 21, 67, 71, 21, 72, 21,
-    73, 74, 21, 75, 76, 21, 77, 78, 21, 21, 76, 21, 79, 80, 21, 21, 81,
+    73, 74, 21, 75, 76, 74, 77, 78, 21, 21, 76, 21, 79, 80, 21, 21, 81,
     21, 21, 21, 21, 21, 21, 21, 82, 21, 21, 83, 21, 21, 83, 21, 21, 21,
     84, 83, 85, 86, 86, 87, 21, 21, 21, 21, 21, 88, 21, 15, 21, 21, 21,
     21, 21, 21, 21, 21, 89, 90, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -654,453 +655,460 @@ static const unsigned char groupMap[] = {
     92, 92, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
     92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 124, 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, 92, 124, 92, 15, 124,
-    124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 92, 124,
-    124, 15, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 92, 92, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 91, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 0,
-    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 0, 0, 15, 15, 15, 15,
-    0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92, 0, 0, 124, 124, 0, 0,
-    124, 124, 92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 15, 15,
-    0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15,
-    4, 4, 18, 18, 18, 18, 18, 18, 14, 4, 0, 0, 0, 0, 0, 92, 92, 124, 0,
-    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 0, 15, 15, 0,
-    0, 92, 0, 124, 124, 124, 92, 92, 0, 0, 0, 0, 92, 92, 0, 0, 92, 92,
-    92, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 0, 0,
-    0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, 92, 15, 15, 15, 92,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
-    15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124,
-    124, 124, 92, 92, 92, 92, 92, 0, 92, 92, 124, 0, 124, 124, 92, 0, 0,
-    15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 92, 92, 0,
-    0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0,
-    0, 0, 0, 0, 0, 0, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15,
-    0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15,
-    15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 92, 124, 92,
-    92, 92, 92, 0, 0, 124, 124, 0, 0, 124, 124, 92, 0, 0, 0, 0, 0, 0, 0,
-    0, 92, 124, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9,
-    9, 9, 9, 9, 9, 9, 9, 9, 14, 15, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 92, 15, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15,
-    15, 0, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 15, 0, 15, 15, 0, 0, 0,
-    15, 15, 0, 0, 0, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 0, 0, 0, 0, 124, 124, 92, 124, 124, 0, 0, 0, 124, 124,
-    124, 0, 124, 124, 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18,
-    18, 18, 14, 14, 14, 14, 14, 14, 4, 14, 0, 0, 0, 0, 0, 92, 124, 124,
-    124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15,
+    92, 92, 92, 124, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 0, 0, 0, 15, 92, 92, 92, 124, 124, 124, 124, 0, 92, 92,
-    92, 0, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 92, 92, 0, 15, 15, 15,
-    0, 0, 0, 0, 0, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
-    0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 14, 0, 92, 124,
-    124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
-    15, 15, 0, 0, 92, 15, 124, 92, 124, 124, 124, 124, 124, 0, 92, 124,
-    124, 0, 124, 124, 92, 92, 0, 0, 0, 0, 0, 0, 0, 124, 124, 0, 0, 0, 0,
-    0, 0, 0, 15, 0, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
-    0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 15, 124, 124, 124, 92, 92, 92, 92, 0, 124,
-    124, 124, 0, 124, 124, 124, 92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0,
-    0, 0, 0, 0, 0, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
-    9, 9, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 15, 15, 15, 15, 15, 15,
-    0, 0, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 0, 0, 0, 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, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15,
-    15, 0, 0, 0, 92, 0, 0, 0, 0, 124, 124, 124, 92, 92, 92, 0, 92, 0, 124,
-    124, 124, 124, 124, 124, 124, 124, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9,
-    9, 9, 9, 9, 9, 0, 0, 124, 124, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 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, 92, 15,
-    15, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 4, 15, 15, 15, 15, 15,
-    15, 91, 92, 92, 92, 92, 92, 92, 92, 92, 3, 9, 9, 9, 9, 9, 9, 9, 9,
-    9, 9, 3, 3, 0, 0, 0, 0, 0, 15, 15, 0, 15, 0, 0, 15, 15, 0, 15, 0, 0,
-    15, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15,
-    0, 15, 15, 15, 0, 15, 0, 15, 0, 0, 15, 15, 0, 15, 15, 15, 15, 92, 15,
-    15, 92, 92, 92, 92, 92, 92, 0, 92, 92, 15, 0, 0, 15, 15, 15, 15, 15,
-    0, 91, 0, 92, 92, 92, 92, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9,
-    9, 0, 0, 15, 15, 15, 15, 15, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    3, 3, 3, 3, 3, 3, 14, 3, 14, 14, 14, 92, 92, 14, 14, 14, 14, 14, 14,
-    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    14, 92, 14, 92, 14, 92, 5, 6, 5, 6, 124, 124, 15, 15, 15, 15, 15, 15,
-    15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 92, 124, 92, 15, 124, 124, 124, 92, 92,
+    92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 92, 124, 124, 15, 92, 92,
+    92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92,
+    3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 91, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 0, 15, 15, 15, 15,
+    15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15,
+    15, 15, 15, 15, 15, 0, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 92, 15, 124,
+    124, 124, 92, 92, 92, 92, 0, 0, 124, 124, 0, 0, 124, 124, 92, 15, 0,
+    0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 92, 92,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18,
+    18, 14, 4, 0, 0, 0, 0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 0,
+    0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 0, 15, 15, 0, 15, 15, 0, 0, 92, 0, 124, 124, 124,
+    92, 92, 0, 0, 0, 0, 92, 92, 0, 0, 92, 92, 92, 0, 0, 0, 92, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 92, 92, 15, 15, 15, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15,
+    0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92,
+    92, 0, 92, 92, 124, 0, 124, 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 3, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 92, 124,
+    124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15,
+    15, 15, 0, 0, 92, 15, 124, 92, 124, 92, 92, 92, 92, 0, 0, 124, 124,
+    0, 0, 124, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, 92, 124, 0, 0, 0, 0, 15,
+    15, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14,
+    15, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 0,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0,
+    0, 0, 15, 15, 0, 15, 0, 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 15, 15, 15,
+    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    124, 124, 92, 124, 124, 0, 0, 0, 124, 124, 124, 0, 124, 124, 124, 92,
+    0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 14, 14, 14, 14, 14,
+    14, 4, 14, 0, 0, 0, 0, 0, 92, 124, 124, 124, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 92,
+    92, 92, 124, 124, 124, 124, 0, 92, 92, 92, 0, 92, 92, 92, 92, 0, 0,
+    0, 0, 0, 0, 0, 92, 92, 0, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 92, 92,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18,
+    18, 18, 18, 18, 18, 14, 15, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 92,
+    124, 124, 124, 124, 124, 0, 92, 124, 124, 0, 124, 124, 92, 92, 0, 0,
+    0, 0, 0, 0, 0, 124, 124, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 15, 92, 92,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 15, 15, 15, 0, 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, 15, 124, 124, 124,
+    92, 92, 92, 92, 0, 124, 124, 124, 0, 124, 124, 124, 92, 15, 14, 0,
+    0, 0, 0, 15, 15, 15, 124, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 92,
+    92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 14, 15, 15, 15, 15, 15, 15, 0, 0, 124, 124, 0, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0,
+    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, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 92, 0, 0, 0, 0, 124,
+    124, 124, 92, 92, 92, 0, 92, 0, 124, 124, 124, 124, 124, 124, 124,
+    124, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 124, 124,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 92, 15, 15, 92, 92, 92, 92, 92, 92, 92,
+    0, 0, 0, 0, 4, 15, 15, 15, 15, 15, 15, 91, 92, 92, 92, 92, 92, 92,
+    92, 92, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, 0, 15, 15,
+    0, 15, 0, 0, 15, 15, 0, 15, 0, 0, 15, 0, 0, 0, 0, 0, 0, 15, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 0, 15, 0,
+    0, 15, 15, 0, 15, 15, 15, 15, 92, 15, 15, 92, 92, 92, 92, 92, 92, 0,
+    92, 92, 15, 0, 0, 15, 15, 15, 15, 15, 0, 91, 0, 92, 92, 92, 92, 92,
+    92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 15, 15, 15, 15, 15, 14,
+    14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 14, 14,
+    14, 92, 92, 14, 14, 14, 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 92, 14, 92, 14, 92, 5, 6, 5,
+    6, 124, 124, 15, 15, 15, 15, 15, 15, 15, 15, 0, 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, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 3, 92, 92, 15, 15, 15,
-    15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 92, 92, 92,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92,
+    92, 92, 92, 3, 92, 92, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
     92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0,
-    14, 14, 14, 14, 14, 14, 14, 14, 92, 14, 14, 14, 14, 14, 14, 0, 14,
-    14, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, 0, 0, 0, 0, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 92, 92, 92, 92, 124, 92,
-    92, 92, 92, 92, 92, 124, 92, 92, 124, 124, 92, 92, 15, 9, 9, 9, 9,
-    9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 124, 124,
-    92, 92, 15, 15, 15, 15, 92, 92, 92, 15, 124, 124, 124, 15, 15, 124,
-    124, 124, 124, 124, 124, 124, 15, 15, 15, 92, 92, 92, 92, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 92, 92, 124,
-    124, 124, 124, 124, 124, 92, 15, 124, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
-    124, 124, 124, 92, 14, 14, 125, 125, 125, 125, 125, 125, 125, 125,
+    92, 92, 92, 92, 92, 92, 92, 92, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    92, 14, 14, 14, 14, 14, 14, 0, 14, 14, 3, 3, 3, 3, 3, 14, 14, 14, 14,
+    3, 3, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124,
+    124, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 124, 92, 92, 124,
+    124, 92, 92, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15,
+    15, 15, 15, 15, 15, 124, 124, 92, 92, 15, 15, 15, 15, 92, 92, 92, 15,
+    124, 124, 124, 15, 15, 124, 124, 124, 124, 124, 124, 124, 15, 15, 15,
+    92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    92, 124, 124, 92, 92, 124, 124, 124, 124, 124, 124, 92, 15, 124, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 124, 124, 124, 92, 14, 14, 125, 125, 125,
     125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
     125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
-    125, 125, 0, 125, 0, 0, 0, 0, 0, 125, 0, 0, 15, 15, 15, 15, 15, 15,
+    125, 125, 125, 125, 125, 125, 125, 0, 125, 0, 0, 0, 0, 0, 125, 0, 0,
     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, 3, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15,
-    15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
-    15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 91, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 0, 0, 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, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0,
-    15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 0, 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, 15, 15, 15, 15,
-    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 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, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0,
-    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 126, 126,
-    126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+    15, 0, 15, 15, 15, 15, 0, 0, 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, 92, 92, 92, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0,
+    0, 0, 0, 0, 0, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
     126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
     126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
-    126, 126, 126, 126, 104, 104, 104, 104, 104, 104, 0, 0, 110, 110, 110,
-    110, 110, 110, 0, 0, 8, 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, 3,
-    3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 2, 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, 5, 6, 0, 0, 0, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, 127, 127, 127, 15, 15,
-    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 92, 92, 92, 0, 0, 0,
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 104, 104, 104, 104, 104,
+    104, 0, 0, 110, 110, 110, 110, 110, 110, 0, 0, 8, 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, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 2, 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, 5,
+    6, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, 127,
+    127, 127, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15,
+    92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 3, 3, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 3, 3, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 92, 92, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 124, 92, 92, 92, 92,
-    92, 92, 92, 124, 124, 124, 124, 124, 124, 124, 124, 92, 124, 124, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 91, 3, 3, 3, 4, 15,
-    92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 8,
-    3, 3, 3, 3, 92, 92, 92, 17, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0,
-    0, 0, 0, 0, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
+    0, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92,
+    124, 92, 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 124, 124, 124,
+    124, 92, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3,
+    3, 91, 3, 3, 3, 4, 15, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0,
+    0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0,
+    0, 3, 3, 3, 3, 3, 3, 8, 3, 3, 3, 3, 92, 92, 92, 17, 0, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 91, 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, 0, 0, 0, 0, 0, 0, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 92, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 15, 92, 92, 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, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 0, 0, 0, 0, 0, 15,
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 0, 92, 92, 92, 124, 124, 124, 124, 92, 92, 124, 124,
-    124, 0, 0, 0, 0, 124, 124, 92, 124, 124, 124, 124, 124, 124, 92, 92,
-    92, 0, 0, 0, 0, 14, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 15, 15, 15, 15,
-    15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 0, 0, 0, 0, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 0, 0, 0, 14, 14, 14,
+    15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 92, 92, 92, 124, 124, 124, 124, 92,
+    92, 124, 124, 124, 0, 0, 0, 0, 124, 124, 92, 124, 124, 124, 124, 124,
+    124, 92, 92, 92, 0, 0, 0, 0, 14, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 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, 15,
+    15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 0, 0, 0,
     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, 92, 92, 124, 124, 92, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 92,
-    124, 92, 92, 92, 92, 92, 92, 92, 0, 92, 124, 92, 124, 124, 92, 92,
-    92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 124, 124, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 0, 0, 92, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0,
-    0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3,
-    3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 0, 0, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 119, 0, 92, 92, 92, 92, 124, 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, 92, 124, 92, 92, 92, 92,
-    92, 124, 92, 124, 124, 124, 124, 124, 92, 124, 124, 15, 15, 15, 15,
-    15, 15, 15, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3,
-    3, 3, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 92, 92, 124,
-    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, 124, 92, 92, 92,
-    92, 124, 124, 92, 92, 124, 92, 92, 92, 15, 15, 9, 9, 9, 9, 9, 9, 9,
-    9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92,
-    92, 124, 124, 124, 92, 124, 92, 92, 92, 124, 124, 0, 0, 0, 0, 0, 0,
-    0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 124, 124, 124, 124, 124, 124, 124,
-    124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 0, 0, 0, 3,
-    3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 15, 15, 15, 9, 9,
-    9, 9, 9, 9, 9, 9, 9, 9, 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, 91, 91, 91, 91, 91, 91, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0,
-    0, 0, 0, 0, 0, 0, 92, 92, 92, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 92,
-    15, 15, 15, 15, 124, 124, 92, 15, 15, 0, 92, 92, 0, 0, 0, 0, 0, 0,
+    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, 92, 92, 124, 124, 92, 0, 0, 3, 3, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 124, 92, 124, 92, 92, 92, 92, 92, 92, 92, 0, 92, 124, 92, 124,
+    124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 124, 124,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 92, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0,
+    0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 0, 0, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 119, 0, 92, 92, 92, 92,
+    124, 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, 92, 124, 92,
+    92, 92, 92, 92, 124, 92, 124, 124, 124, 124, 124, 92, 124, 124, 15,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3,
+    3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+    92, 92, 124, 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, 124,
+    92, 92, 92, 92, 124, 124, 92, 92, 124, 92, 92, 92, 15, 15, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    92, 124, 92, 92, 124, 124, 124, 92, 124, 92, 92, 92, 124, 124, 0, 0,
+    0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 124, 124, 124, 124, 124,
+    124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 0,
+    0, 0, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 15, 15,
+    15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 91, 91, 91, 91, 91, 91, 3, 3, 128, 129, 130, 131, 131,
+    132, 133, 134, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+    92, 92, 92, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    124, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 92, 15, 15, 15, 15,
+    124, 124, 92, 15, 15, 0, 92, 92, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 91, 91,
+    21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
     91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
     91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
     91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-    91, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 91, 128, 21, 21, 21, 129, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 92,
-    92, 92, 92, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
-    23, 24, 23, 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 130, 21, 21, 131,
-    21, 132, 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133,
-    133, 133, 133, 132, 132, 132, 132, 132, 132, 0, 0, 133, 133, 133, 133,
-    133, 133, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 133, 133, 133,
-    133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 133,
-    133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 0,
-    0, 133, 133, 133, 133, 133, 133, 0, 0, 21, 132, 21, 132, 21, 132, 21,
-    132, 0, 133, 0, 133, 0, 133, 0, 133, 132, 132, 132, 132, 132, 132,
-    132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 135, 135,
-    135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 0, 0, 132, 132, 132,
-    132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140, 140, 132,
-    132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140,
-    140, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140,
-    140, 140, 140, 132, 132, 21, 141, 21, 0, 21, 21, 133, 133, 142, 142,
-    143, 11, 144, 11, 11, 11, 21, 141, 21, 0, 21, 21, 145, 145, 145, 145,
-    143, 11, 11, 11, 132, 132, 21, 21, 0, 0, 21, 21, 133, 133, 146, 146,
-    0, 11, 11, 11, 132, 132, 21, 21, 21, 113, 21, 21, 133, 133, 147, 147,
-    117, 11, 11, 11, 0, 0, 21, 141, 21, 0, 21, 21, 148, 148, 149, 149,
-    143, 11, 11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 17,
-    8, 8, 8, 8, 8, 8, 3, 3, 16, 20, 5, 16, 16, 20, 5, 16, 3, 3, 3, 3, 3,
-    3, 3, 3, 150, 151, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    16, 20, 3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 3, 3, 3, 3, 3, 3, 3,
-    3, 3, 3, 3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 17, 17, 17,
-    17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 91, 0, 0, 18,
-    18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 91, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 7, 7, 7, 5, 6, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-    91, 91, 91, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 119, 119, 119, 119, 92, 119, 119, 119, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 14, 14, 107, 14, 14, 14, 14, 107, 14, 14, 21, 107, 107, 107,
-    21, 21, 107, 107, 107, 21, 14, 107, 14, 14, 7, 107, 107, 107, 107,
-    107, 14, 14, 14, 14, 14, 14, 107, 14, 152, 14, 107, 14, 153, 154, 107,
-    107, 14, 21, 107, 107, 155, 107, 21, 15, 15, 15, 15, 21, 14, 14, 21,
-    21, 107, 107, 7, 7, 7, 7, 7, 107, 21, 21, 21, 21, 14, 7, 14, 14, 156,
-    14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
-    157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
-    158, 158, 158, 158, 127, 127, 127, 23, 24, 127, 127, 127, 127, 18,
-    14, 14, 0, 0, 0, 0, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 7, 7, 14, 14,
-    14, 14, 7, 14, 14, 7, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 7, 14,
+    91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 136, 21,
+    21, 21, 137, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 91,
+    91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92,
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 138, 21, 21, 139, 21, 140,
+    140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141,
+    141, 140, 140, 140, 140, 140, 140, 0, 0, 141, 141, 141, 141, 141, 141,
+    0, 0, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141,
+    141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141,
+    141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 0, 0, 141, 141,
+    141, 141, 141, 141, 0, 0, 21, 140, 21, 140, 21, 140, 21, 140, 0, 141,
+    0, 141, 0, 141, 0, 141, 140, 140, 140, 140, 140, 140, 140, 140, 141,
+    141, 141, 141, 141, 141, 141, 141, 142, 142, 143, 143, 143, 143, 144,
+    144, 145, 145, 146, 146, 147, 147, 0, 0, 140, 140, 140, 140, 140, 140,
+    140, 140, 148, 148, 148, 148, 148, 148, 148, 148, 140, 140, 140, 140,
+    140, 140, 140, 140, 148, 148, 148, 148, 148, 148, 148, 148, 140, 140,
+    140, 140, 140, 140, 140, 140, 148, 148, 148, 148, 148, 148, 148, 148,
+    140, 140, 21, 149, 21, 0, 21, 21, 141, 141, 150, 150, 151, 11, 152,
+    11, 11, 11, 21, 149, 21, 0, 21, 21, 153, 153, 153, 153, 151, 11, 11,
+    11, 140, 140, 21, 21, 0, 0, 21, 21, 141, 141, 154, 154, 0, 11, 11,
+    11, 140, 140, 21, 21, 21, 113, 21, 21, 141, 141, 155, 155, 117, 11,
+    11, 11, 0, 0, 21, 149, 21, 0, 21, 21, 156, 156, 157, 157, 151, 11,
+    11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 17, 8, 8, 8,
+    8, 8, 8, 3, 3, 16, 20, 5, 16, 16, 20, 5, 16, 3, 3, 3, 3, 3, 3, 3, 3,
+    158, 159, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 20,
+    3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 17, 17, 17, 17, 17, 0,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 91, 0, 0, 18, 18, 18, 18,
+    18, 18, 7, 7, 7, 5, 6, 91, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    7, 7, 7, 5, 6, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    119, 119, 119, 119, 92, 119, 119, 119, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+    14, 107, 14, 14, 14, 14, 107, 14, 14, 21, 107, 107, 107, 21, 21, 107,
+    107, 107, 21, 14, 107, 14, 14, 7, 107, 107, 107, 107, 107, 14, 14,
+    14, 14, 14, 14, 107, 14, 160, 14, 107, 14, 161, 162, 107, 107, 14,
+    21, 107, 107, 163, 107, 21, 15, 15, 15, 15, 21, 14, 14, 21, 21, 107,
+    107, 7, 7, 7, 7, 7, 107, 21, 21, 21, 21, 14, 7, 14, 14, 164, 14, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 165, 165,
+    165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+    166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+    166, 166, 127, 127, 127, 23, 24, 127, 127, 127, 127, 18, 14, 14, 0,
+    0, 0, 0, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 7,
+    14, 14, 7, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 7, 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, 7, 7, 14, 14, 7,
-    14, 7, 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, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14,
-    14, 14, 14, 14, 14, 14, 5, 6, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14,
-    14, 14, 14, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 7, 14, 7, 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, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14,
+    14, 14, 14, 5, 6, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 14, 14, 14,
+    5, 6, 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, 7, 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, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 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, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14,
     14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 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, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 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, 159, 159, 159, 159, 159, 159, 159,
-    159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159,
-    159, 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, 160,
-    160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
-    160, 160, 160, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 167, 167, 167, 167, 167, 167, 167, 167,
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
+    167, 167, 167, 167, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
+    168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
+    168, 168, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 7, 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, 7, 7, 7, 7, 7, 7, 7,
-    7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 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, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 18,
+    14, 14, 14, 14, 14, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 18, 18,
     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 5, 6, 7, 7, 7, 7, 7, 7,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7,
     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
-    6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 7, 7, 7, 7,
+    5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
+    6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7,
     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 5, 6, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 14, 14, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14,
+    7, 7, 7, 5, 6, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 14, 14, 7, 7, 7, 7, 7, 7, 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, 0,
-    0, 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, 0,
-    0, 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, 0, 0, 14, 14,
     14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14,
-    14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 122, 122, 122,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 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, 0, 0, 0, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
     122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
     122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
-    122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 0, 123,
+    122, 122, 122, 122, 122, 122, 122, 122, 122, 0, 123, 123, 123, 123,
     123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
     123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
     123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
-    123, 123, 123, 123, 0, 23, 24, 161, 162, 163, 164, 165, 23, 24, 23,
-    24, 23, 24, 166, 167, 168, 169, 21, 23, 24, 21, 23, 24, 21, 21, 21,
-    21, 21, 91, 91, 170, 170, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14,
-    23, 24, 23, 24, 92, 92, 92, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18,
-    3, 3, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-    171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-    171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 171, 0, 0,
-    0, 0, 0, 171, 0, 0, 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, 0, 0, 0, 0, 0,
-    91, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 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, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15,
-    15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
-    15, 15, 15, 15, 0, 3, 3, 16, 20, 16, 20, 3, 3, 3, 16, 20, 3, 16, 20,
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 3, 3, 8, 3, 16, 20, 3, 3, 16, 20, 5,
-    6, 5, 6, 5, 6, 5, 6, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    3, 8, 8, 3, 3, 3, 3, 8, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14,
+    123, 0, 23, 24, 169, 170, 171, 172, 173, 23, 24, 23, 24, 23, 24, 174,
+    175, 176, 177, 21, 23, 24, 21, 23, 24, 21, 21, 21, 21, 21, 91, 91,
+    178, 178, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, 23, 24, 23, 24,
+    92, 92, 92, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, 3, 3, 179, 179,
+    179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
+    179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
+    179, 179, 179, 179, 179, 179, 179, 179, 0, 179, 0, 0, 0, 0, 0, 179,
+    0, 0, 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, 0, 0, 0, 0, 0, 91, 3, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 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, 0,
+    0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+    0, 3, 3, 16, 20, 16, 20, 3, 3, 3, 16, 20, 3, 16, 20, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 8, 3, 3, 8, 3, 16, 20, 3, 3, 16, 20, 5, 6, 5, 6, 5, 6,
+    5, 6, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3,
+    3, 3, 8, 3, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 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, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 2, 3, 3, 3, 14, 91, 15,
-    127, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 5, 6, 5, 6,
-    8, 5, 6, 6, 14, 127, 127, 127, 127, 127, 127, 127, 127, 127, 92, 92,
-    92, 92, 124, 124, 8, 91, 91, 91, 91, 91, 14, 14, 127, 127, 127, 91,
-    15, 3, 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, 0, 0, 92, 92, 11, 11, 91, 91,
-    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, 3, 91, 91, 91, 15, 0, 0,
-    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 0, 2, 3, 3, 3, 14, 91, 15, 127, 5, 6, 5, 6, 5,
+    6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 5, 6, 5, 6, 8, 5, 6, 6, 14, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 92, 92, 92, 92, 124, 124, 8,
+    91, 91, 91, 91, 91, 14, 14, 127, 127, 127, 91, 15, 3, 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, 0, 0, 92, 92, 11, 11, 91, 91, 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, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 3, 91, 91, 91, 15, 0, 0, 0, 0, 0, 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, 14, 14, 18, 18, 18, 18, 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,
-    0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14,
+    15, 15, 15, 0, 0, 0, 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, 14, 14, 18, 18, 18, 18, 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, 0, 0, 0, 0, 0, 14, 14,
+    14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 0, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 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, 18, 18, 18,
+    18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 91, 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, 0, 14, 14,
     14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15,
+    14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 91, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 15, 92, 119, 119, 119,
+    3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 91, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 23, 24, 23, 24, 91, 91, 92, 92, 15, 15, 15, 15, 15, 15, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 92, 92, 3, 3, 3, 3, 3,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 91, 91, 91, 91,
+    91, 91, 91, 91, 91, 11, 11, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 91, 21, 21, 21, 21, 21, 21, 21, 21, 23, 24, 23, 24, 180, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 11, 11, 23, 24, 181, 21, 15,
+    23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 182, 183, 184, 185, 182, 0, 186,
+    187, 188, 189, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 91, 91,
+    21, 15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 15, 92, 15, 15, 15, 15,
+    92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 124, 124, 92, 92, 124, 14, 14, 14, 14,
+    0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 14, 14, 4, 14, 0, 0, 0, 0, 0, 0,
     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, 91, 3, 3, 3, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9,
-    9, 9, 9, 9, 9, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
-    24, 15, 92, 119, 119, 119, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    3, 91, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 91, 92, 92,
-    15, 15, 15, 15, 15, 15, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 92, 92, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 91, 91, 91, 91, 91, 91, 91, 91, 91, 11, 11, 23, 24, 23,
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 21, 21, 23, 24, 23, 24,
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 21, 21, 21, 21, 21, 21, 21,
-    21, 23, 24, 23, 24, 172, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 91,
-    11, 11, 23, 24, 173, 21, 15, 23, 24, 23, 24, 21, 21, 23, 24, 23, 24,
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 174,
-    175, 176, 177, 0, 0, 178, 179, 180, 181, 23, 24, 23, 24, 0, 0, 0, 0,
+    15, 15, 15, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 124, 124, 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, 124, 124, 124,
+    124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 92,
+    92, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0,
+    0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, 3, 15, 0,
+    0, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124,
+    124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 92, 92, 92, 92, 124,
+    124, 92, 124, 124, 124, 124, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    0, 91, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15,
+    15, 15, 92, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 124, 124, 92, 92, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, 15,
+    15, 92, 124, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 3, 3, 3, 3,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91,
+    15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 124, 92, 124, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 92,
+    92, 92, 15, 15, 92, 92, 15, 15, 15, 15, 15, 92, 92, 15, 92, 15, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 15, 91, 91, 21, 15, 15, 15, 15, 15, 15, 15, 92, 15, 15,
-    15, 92, 15, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 92, 92,
-    124, 14, 14, 14, 14, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 14, 14, 4,
-    14, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
-    124, 124, 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, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
-    124, 124, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9,
-    9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 3, 3, 3,
-    15, 3, 15, 0, 0, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92,
-    92, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 124, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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, 0, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 92, 92,
-    92, 92, 124, 124, 92, 124, 124, 124, 124, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    3, 3, 3, 3, 0, 91, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3,
-    15, 15, 15, 15, 15, 92, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9,
-    9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 124, 124,
-    92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 92, 15, 15, 15, 15,
-    15, 15, 15, 15, 92, 124, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0,
-    3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 91, 15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 124, 92, 124, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    92, 15, 92, 92, 92, 15, 15, 92, 92, 15, 15, 15, 15, 15, 92, 92, 15,
-    92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 15, 15, 91, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 124, 92, 92, 124, 124, 3, 3, 15, 91, 91, 124, 92, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15,
-    0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15,
-    15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 21, 21, 21, 21, 21,
+    15, 15, 91, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124,
+    92, 92, 124, 124, 3, 3, 15, 91, 91, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15,
+    15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 21, 21, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 182, 21, 21, 21,
-    21, 21, 21, 21, 11, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
-    183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
-    183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
-    183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 15, 15, 15, 124,
-    124, 92, 124, 124, 92, 124, 124, 3, 124, 92, 0, 0, 9, 9, 9, 9, 9, 9,
-    9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 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, 0, 0, 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, 0, 0, 184, 184, 184,
-    184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
-    184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
-    184, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
-    185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
-    185, 185, 185, 185, 185, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 190, 21, 21, 21, 21, 21,
+    21, 21, 11, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+    191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+    191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+    191, 191, 191, 191, 191, 191, 191, 191, 191, 15, 15, 15, 124, 124,
+    92, 124, 124, 92, 124, 124, 3, 124, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 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, 0, 0, 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, 0, 0, 192, 192, 192,
+    192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+    192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+    192, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193,
+    193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193,
+    193, 193, 193, 193, 193, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
     15, 15, 15, 0, 0, 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, 0, 0, 0, 0, 21,
@@ -1155,229 +1163,263 @@ static const unsigned char groupMap[] = {
     127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
     127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 18,
     18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 18, 18, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    14, 14, 14, 18, 18, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 18,
+    14, 14, 14, 92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92,
     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 18, 18, 18, 18, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 127, 15, 15, 15, 15, 15, 15, 15, 15,
-    127, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 18, 18, 18, 18,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 15, 15, 15, 15, 15, 15, 15,
+    15, 127, 0, 0, 0, 0, 0, 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, 92, 92, 92, 92, 92, 0, 0, 0, 0,
-    0, 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, 92, 92, 92, 92, 92, 0, 0, 0,
+    0, 0, 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, 3, 15, 15,
     15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 127, 127, 127,
-    127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 186, 186, 186, 186, 186,
-    186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
-    186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
-    186, 186, 186, 186, 186, 186, 187, 187, 187, 187, 187, 187, 187, 187,
-    187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
-    187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
-    187, 187, 187, 187, 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,
+    127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 0, 0, 0, 0, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0,
+    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15,
+    0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0,
-    0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
-    15, 0, 0, 15, 0, 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, 15, 15, 0, 0, 0, 15,
+    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 3, 18, 18, 18, 18, 18, 18, 18, 18, 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, 15, 15,
-    0, 0, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 18, 18, 18, 18, 18,
-    18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18,
-    18, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0,
-    0, 0, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18,
-    0, 0, 0, 3, 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, 0, 0, 0, 3, 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, 0, 0, 18, 18, 15, 15, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 15, 92, 92, 92, 0, 92, 92,
-    0, 0, 0, 0, 0, 92, 92, 92, 92, 15, 15, 15, 15, 0, 15, 15, 15, 0, 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, 0, 0, 92, 92, 92, 0, 0, 0,
-    0, 92, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3,
-    3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 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, 18, 18, 3, 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, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 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, 92, 92, 0, 0, 0, 0, 18, 18, 18,
-    18, 18, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 18, 18,
-    18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18,
-    18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97,
+    15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0,
+    0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 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, 0, 0, 0, 3, 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, 0, 0, 18, 18, 15, 15, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 15, 92, 92, 92, 0, 92, 92, 0, 0, 0, 0, 0, 92,
+    92, 92, 92, 15, 15, 15, 15, 0, 15, 15, 15, 0, 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, 0, 0, 92, 92, 92, 0, 0, 0, 0, 92, 18, 18, 18,
+    18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 0, 0, 0, 0, 0, 0, 0, 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, 18, 18, 3, 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, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 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, 92, 92, 0, 0, 0, 0, 18, 18, 18, 18, 18, 3, 3, 3,
+    3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0,
+    3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 97, 97, 97, 97, 97,
     97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
     97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
-    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102,
-    102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
     102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
     102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
-    102, 102, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0,
+    0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 124, 92, 124, 15, 15,
+    18, 18, 18, 18, 18, 18, 0, 124, 92, 124, 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, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 0, 0,
+    0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 124, 124, 92,
+    92, 3, 3, 17, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3,
-    3, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92,
-    92, 124, 124, 92, 92, 3, 3, 17, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0,
-    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 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,
-    92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 9, 9, 9,
-    9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 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, 92, 92, 92, 92,
+    92, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15,
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 92, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 15, 15, 15, 15, 3, 3,
-    3, 3, 3, 92, 92, 92, 3, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 3,
-    15, 3, 3, 3, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 3, 3, 15,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 124, 124, 15, 15, 15, 15, 3, 3, 3, 3, 3, 92, 92,
+    92, 3, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 3, 15, 3, 3, 3, 0, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 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, 124, 124, 124, 92, 92, 92, 124, 124,
-    92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 0, 0, 15, 15, 15, 15, 15, 15, 15,
-    0, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 0,
-    0, 0, 0, 0, 0, 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,
-    92, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9,
-    9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 124, 124, 0, 15,
-    15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 124, 124, 0, 0, 124,
-    124, 0, 0, 124, 124, 124, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0,
-    0, 0, 15, 15, 15, 15, 15, 124, 124, 0, 0, 92, 92, 92, 92, 92, 92, 92,
-    0, 0, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124,
-    92, 92, 92, 92, 92, 92, 124, 92, 124, 124, 124, 124, 92, 92, 124, 92,
-    92, 15, 15, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
-    9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 0, 0, 124, 124, 124,
-    124, 92, 92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 92, 92, 0, 0, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124,
-    92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 124, 92, 92, 3, 3, 3,
-    15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
-    0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124,
-    92, 124, 124, 92, 92, 92, 92, 92, 92, 124, 92, 0, 0, 0, 0, 0, 0, 0,
-    0, 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, 0, 92, 92, 92, 124, 124,
-    92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 0, 0, 0, 0, 9, 9, 9, 9, 9,
-    9, 9, 9, 9, 9, 18, 18, 3, 3, 3, 14, 10, 10, 10, 10, 10, 10, 10, 10,
+    15, 15, 15, 124, 124, 124, 92, 92, 92, 124, 124, 92, 124, 92, 92, 3,
+    3, 3, 3, 3, 3, 92, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 0, 0, 0, 0, 0, 0,
+    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, 92, 124, 124, 124,
+    92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 124, 124, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 92, 124, 124, 124, 124, 0, 0, 124, 124, 0, 0, 124,
+    124, 124, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 15, 15, 15,
+    15, 15, 124, 124, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 92, 92,
+    92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124,
+    124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 92, 124, 92,
+    15, 15, 15, 15, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 3,
+    0, 3, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 124, 92, 124, 124, 124,
+    124, 92, 92, 124, 92, 92, 15, 15, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92,
+    0, 0, 124, 124, 124, 124, 92, 92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 92,
+    92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 124,
+    92, 92, 3, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, 124, 124, 92, 92,
+    92, 92, 92, 92, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 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, 0, 92, 92, 92, 124,
+    124, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 0, 0, 0, 0, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 18, 18, 3, 3, 3, 14, 10, 10, 10, 10, 10, 10, 10,
     10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    10, 10, 10, 10, 10, 10, 10, 10, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15,
+    13, 13, 13, 13, 13, 13, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 3, 3, 3, 3, 3, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 0, 0, 92, 92, 92, 92, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 3, 3, 14, 14, 14, 14, 91, 91,
-    91, 91, 3, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
-    9, 9, 0, 18, 18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
-    0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
-    15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 124, 124, 124, 124,
-    124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 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, 124, 92, 92, 92, 92, 92, 92, 92, 0, 124,
+    124, 124, 124, 92, 92, 124, 92, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 3, 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, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 0, 124, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92, 124, 92, 92, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 92, 92, 92, 92, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92,
+    92, 92, 92, 92, 3, 3, 3, 3, 3, 14, 14, 14, 14, 91, 91, 91, 91, 3, 14,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 18,
+    18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 124, 124, 124, 124, 124, 124,
     124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
     124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 91,
-    91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 15, 15, 0, 0, 0, 0,
+    124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 91, 91, 91,
+    91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 0, 0, 14, 92, 92, 3, 17, 17, 17, 17, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 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, 124, 124, 92, 92, 92, 14, 14, 14, 124, 124, 124, 124, 124,
-    124, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, 92, 92, 92, 92, 92,
-    14, 14, 92, 92, 92, 92, 92, 92, 92, 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, 92, 92, 92, 92, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 14, 14, 92, 92, 92, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0,
+    14, 92, 92, 3, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14,
+    14, 14, 0, 0, 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, 124, 124, 92,
+    92, 92, 14, 14, 14, 124, 124, 124, 124, 124, 124, 17, 17, 17, 17, 17,
+    17, 17, 17, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 92, 92, 92, 92,
+    92, 92, 92, 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, 92,
+    92, 92, 92, 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, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 92, 92,
+    92, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21,
+    21, 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, 21,
+    107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 0,
+    107, 107, 0, 0, 107, 0, 0, 107, 107, 0, 0, 107, 107, 107, 107, 0, 107,
+    107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 0, 21, 0, 21, 21,
+    21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 0,
+    107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107,
+    107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107,
+    107, 107, 0, 107, 107, 107, 107, 107, 0, 107, 0, 0, 0, 107, 107, 107,
+    107, 107, 107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 107, 0, 107, 107, 0, 0, 107, 0, 0, 107, 107, 0, 0,
-    107, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 21,
-    21, 21, 21, 0, 21, 0, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107,
+    21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 0,
-    107, 107, 107, 107, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 0,
-    107, 107, 107, 107, 107, 107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 107, 107, 0, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, 0,
-    107, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 0, 21, 21, 21, 21,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 0, 0, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107,
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 21, 21, 21,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107,
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21,
-    21, 21, 21, 21, 21, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7,
+    21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
     107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21,
@@ -1388,60 +1430,62 @@ static const unsigned char groupMap[] = {
     107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
     107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21,
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21,
-    21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
-    7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107,
-    21, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 21, 0, 0, 9, 9, 9, 9, 9, 9,
     9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
-    9, 9, 9, 9, 9, 9, 9, 9, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 92,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92,
     92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-    14, 14, 14, 14, 14, 14, 14, 14, 92, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 92, 14, 14, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92,
-    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    92, 92, 92, 92, 92, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14,
+    14, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92,
+    14, 14, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92,
+    92, 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 92,
+    92, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18,
     18, 18, 18, 18, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 15, 15, 15, 15, 0, 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, 15,
-    15, 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0,
-    15, 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15,
-    0, 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 0,
-    15, 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 0, 15, 15,
-    15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15,
-    15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 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, 0, 0, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18,
-    18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    0, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+    196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+    196, 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197,
+    197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197,
+    197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 92,
+    92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 0, 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, 15, 15, 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15,
+    0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0,
+    15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15,
+    15, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+    0, 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, 0, 0, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 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, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 0, 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, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 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, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 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, 11, 11, 11, 11, 11, 14,
-    14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0,
+    0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    14, 14, 14, 14, 14, 14, 14, 14, 11, 11, 11, 11, 11, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
     14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14,
     14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14,
@@ -1450,8 +1494,14 @@ static const unsigned char groupMap[] = {
     14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
     14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0,
+    0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0
 #endif /* TCL_UTF_MAX > 3 */
 };
 
@@ -1486,15 +1536,16 @@ static const int groups[] = {
     29761, 9793, 9537, 16449, 16193, 9858, 9602, 8066, 16514, 16258,
     2113, 16002, 14722, 1, 12162, 13954, 2178, 22146, 20610, -1662,
     29826, -15295, 24706, -1727, 20545, 7, 3905, 3970, 12353, 12418,
-    8, 1859649, 9949249, 10, -9044862, -976254, 15234, -1949375, -1918,
-    -1983, -18814, -21886, -25470, -32638, -28542, -32126, -1981,
-    -2174, -18879, -2237, 1844610, -21951, -25535, -28607, -32703,
-    -32191, 13, 14, -1924287, -2145983, -2115007, 7233, 7298, 4170,
-    4234, 6749, 6813, -2750143, -976319, -2746047, 2763650, 2762882,
-    -2759615, -2751679, -2760383, -2760127, -2768575, 1859714, -9044927,
-    -10823615, -10830783, -10833599, -10832575, -10830015, -10817983,
-    -10824127, -10818751, 237633, 237698, 9949314, 18, 17, 10305,
-    10370
+    8, 1859649, 9949249, 10, 1601154, 1600898, 1598594, 1598082, 1598338,
+    1596546, 1582466, -9027966, -9044862, -976254, 15234, -1949375,
+    -1918, -1983, -18814, -21886, -25470, -32638, -28542, -32126,
+    -1981, -2174, -18879, -2237, 1844610, -21951, -25535, -28607,
+    -32703, -32191, 13, 14, -1924287, -2145983, -2115007, 7233, 7298,
+    4170, 4234, 6749, 6813, -2750143, -976319, -2746047, 2763650,
+    2762882, -2759615, -2751679, -2760383, -2760127, -2768575, 1859714,
+    -9044927, -10823615, -10830783, -10833599, -10832575, -10830015,
+    -10817983, -10824127, -10818751, 237633, 237698, 9949314, 18,
+    17, 10305, 10370, 8769, 8834
 };
 
 #if TCL_UTF_MAX > 3
index 2b0fb72..553593c 100644 (file)
@@ -2634,7 +2634,19 @@ Tcl_DStringAppend(
            memcpy(newString, dsPtr->string, (size_t) dsPtr->length);
            dsPtr->string = newString;
        } else {
+           int offset = -1;
+
+           /* See [16896d49fd] */
+           if (bytes >= dsPtr->string
+                   && bytes <= dsPtr->string + dsPtr->length) {
+               offset = bytes - dsPtr->string;
+           }
+
            dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl);
+
+           if (offset >= 0) {
+               bytes = dsPtr->string + offset;
+           }
        }
     }
 
@@ -2725,7 +2737,19 @@ Tcl_DStringAppendElement(
            memcpy(newString, dsPtr->string, (size_t) dsPtr->length);
            dsPtr->string = newString;
        } else {
+           int offset = -1;
+
+           /* See [16896d49fd] */
+           if (element >= dsPtr->string
+                   && element <= dsPtr->string + dsPtr->length) {
+               offset = element - dsPtr->string;
+           }
+
            dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl);
+
+           if (offset >= 0) {
+               element = dsPtr->string + offset;
+           }
        }
        dst = dsPtr->string + dsPtr->length;
     }
index 451ef7b..2adffbc 100644 (file)
@@ -219,10 +219,6 @@ static Tcl_SetFromAnyProc  PanicOnSetVarName;
  *                       or NULL if it is this same obj
  *   twoPtrValue.ptr2: index into locals table
  *
- * nsVarName - INTERNALREP DEFINITION:
- *   twoPtrValue.ptr1: pointer to the namespace containing the reference
- *   twoPtrValue.ptr2: pointer to the corresponding Var
- *
  * parsedVarName - INTERNALREP DEFINITION:
  *   twoPtrValue.ptr1: pointer to the array name Tcl_Obj, or NULL if it is a
  *                     scalar variable
@@ -697,13 +693,16 @@ TclObjLookupVarEx(
        /*
         * An indexed local variable.
         */
+       Tcl_Obj *cachedNamePtr = localName(iPtr->varFramePtr, index);
 
        part1Ptr->typePtr = &localVarNameType;
-       if (part1Ptr != localName(iPtr->varFramePtr, index)) {
-           part1Ptr->internalRep.twoPtrValue.ptr1 =
-                   localName(iPtr->varFramePtr, index);
-           Tcl_IncrRefCount((Tcl_Obj *)
-                   part1Ptr->internalRep.twoPtrValue.ptr1);
+       if (part1Ptr != cachedNamePtr) {
+           part1Ptr->internalRep.twoPtrValue.ptr1 = cachedNamePtr;
+           Tcl_IncrRefCount(cachedNamePtr);
+           if (cachedNamePtr->typePtr != &localVarNameType
+                   || cachedNamePtr->internalRep.twoPtrValue.ptr1 != NULL) {
+               TclFreeIntRep(cachedNamePtr);
+           }
        } else {
            part1Ptr->internalRep.twoPtrValue.ptr1 = NULL;
        }
@@ -739,21 +738,6 @@ TclObjLookupVarEx(
 }
 \f
 /*
- * This flag bit should not interfere with TCL_GLOBAL_ONLY,
- * TCL_NAMESPACE_ONLY, or TCL_LEAVE_ERR_MSG; it signals that the variable
- * lookup is performed for upvar (or similar) purposes, with slightly
- * different rules:
- *    - Bug #696893 - variable is either proc-local or in the current
- *     namespace; never follow the second (global) resolution path
- *    - Bug #631741 - do not use special namespace or interp resolvers
- *
- * It should also not collide with the (deprecated) TCL_PARSE_PART1 flag
- * (Bug #835020)
- */
-
-#define AVOID_RESOLVERS 0x40000
-
-/*
  *----------------------------------------------------------------------
  *
  * TclLookupSimpleVar --
@@ -802,8 +786,8 @@ TclLookupSimpleVar(
     Tcl_Obj *varNamePtr,       /* This is a simple variable name that could
                                 * represent a scalar or an array. */
     int flags,                 /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
-                                * AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG bits
-                                * matter. */
+                                * TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG
+                                * bits matter. */
     const int create,          /* If 1, create hash table entry for varname,
                                 * if it doesn't already exist. If 0, return
                                 * error if it doesn't exist. */
@@ -843,7 +827,7 @@ TclLookupSimpleVar(
      */
 
     if ((cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL)
-           && !(flags & AVOID_RESOLVERS)) {
+           && !(flags & TCL_AVOID_RESOLVERS)) {
        resPtr = iPtr->resolverPtr;
        if (cxtNsPtr->varResProc) {
            result = cxtNsPtr->varResProc(interp, varName,
@@ -896,7 +880,7 @@ TclLookupSimpleVar(
            *indexPtr = -1;
            flags = (flags | TCL_GLOBAL_ONLY) & ~TCL_NAMESPACE_ONLY;
        } else {
-           if (flags & AVOID_RESOLVERS) {
+           if (flags & TCL_AVOID_RESOLVERS) {
                flags = (flags | TCL_NAMESPACE_ONLY);
            }
            if (flags & TCL_NAMESPACE_ONLY) {
@@ -911,7 +895,7 @@ TclLookupSimpleVar(
 
        varPtr = (Var *) ObjFindNamespaceVar(interp, varNamePtr,
                (Tcl_Namespace *) cxtNsPtr,
-               (flags | AVOID_RESOLVERS) & ~TCL_LEAVE_ERR_MSG);
+               (flags | TCL_AVOID_RESOLVERS) & ~TCL_LEAVE_ERR_MSG);
        if (varPtr == NULL) {
            Tcl_Obj *tailPtr;
 
@@ -4393,15 +4377,15 @@ TclPtrObjMakeUpvar(
 
        /*
         * Lookup and eventually create the new variable. Set the flag bit
-        * AVOID_RESOLVERS to indicate the special resolution rules for upvar
-        * purposes:
+        * TCL_AVOID_RESOLVERS to indicate the special resolution rules for
+        * upvar purposes:
         *   - Bug #696893 - variable is either proc-local or in the current
         *     namespace; never follow the second (global) resolution path.
         *   - Bug #631741 - do not use special namespace or interp resolvers.
         */
 
        varPtr = TclLookupSimpleVar(interp, myNamePtr,
-               myFlags|AVOID_RESOLVERS, /* create */ 1, &errMsg, &index);
+               myFlags|TCL_AVOID_RESOLVERS, /* create */ 1, &errMsg, &index);
        if (varPtr == NULL) {
            TclObjVarErrMsg(interp, myNamePtr, NULL, "create", errMsg, -1);
            Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
@@ -4935,7 +4919,8 @@ Tcl_UpvarObjCmd(
 
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                "bad level \"%s\"", TclGetString(levelObj)));
-       Tcl_SetErrorCode(interp, "TCL", "VALUE", "LEVEL", NULL);
+       Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
+               TclGetString(levelObj), NULL);
        return TCL_ERROR;
     }
 
@@ -5691,11 +5676,12 @@ Tcl_FindNamespaceVar(
                                 * Otherwise, points to namespace in which to
                                 * resolve name. If NULL, look up name in the
                                 * current namespace. */
-    int flags)                 /* An OR'd combination of: AVOID_RESOLVERS,
-                                * TCL_GLOBAL_ONLY (look up name only in
-                                * global namespace), TCL_NAMESPACE_ONLY (look
-                                * up only in contextNsPtr, or the current
-                                * namespace if contextNsPtr is NULL), and
+    int flags)                 /* An OR'd combination of:
+                                * TCL_AVOID_RESOLVERS, TCL_GLOBAL_ONLY (look
+                                * up name only in global namespace),
+                                * TCL_NAMESPACE_ONLY (look up only in
+                                * contextNsPtr, or the current namespace if
+                                * contextNsPtr is NULL), and
                                 * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
                                 * and TCL_NAMESPACE_ONLY are given,
                                 * TCL_GLOBAL_ONLY is ignored. */
@@ -5721,11 +5707,12 @@ ObjFindNamespaceVar(
                                 * Otherwise, points to namespace in which to
                                 * resolve name. If NULL, look up name in the
                                 * current namespace. */
-    int flags)                 /* An OR'd combination of: AVOID_RESOLVERS,
-                                * TCL_GLOBAL_ONLY (look up name only in
-                                * global namespace), TCL_NAMESPACE_ONLY (look
-                                * up only in contextNsPtr, or the current
-                                * namespace if contextNsPtr is NULL), and
+    int flags)                 /* An OR'd combination of:
+                                * TCL_AVOID_RESOLVERS, TCL_GLOBAL_ONLY (look
+                                * up name only in global namespace),
+                                * TCL_NAMESPACE_ONLY (look up only in
+                                * contextNsPtr, or the current namespace if
+                                * contextNsPtr is NULL), and
                                 * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
                                 * and TCL_NAMESPACE_ONLY are given,
                                 * TCL_GLOBAL_ONLY is ignored. */
@@ -5755,7 +5742,7 @@ ObjFindNamespaceVar(
        cxtNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
     }
 
-    if (!(flags & AVOID_RESOLVERS) &&
+    if (!(flags & TCL_AVOID_RESOLVERS) &&
            (cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL)) {
        resPtr = iPtr->resolverPtr;
 
index 50d9a30..dac47cf 100644 (file)
@@ -1194,11 +1194,12 @@ Tcl_ZlibStreamPut(
        zshPtr->stream.next_out = (Bytef *) dataTmp;
 
        e = deflate(&zshPtr->stream, flush);
-       while (e == Z_BUF_ERROR) {
+       while (e == Z_BUF_ERROR || (flush == Z_FINISH && e == Z_OK)) {
            /*
-            * Output buffer too small to hold the data being generated; so
-            * put a new buffer into place after saving the old generated
-            * data to the outData list.
+            * Output buffer too small to hold the data being generated or we
+            * are doing the end-of-stream flush (which can spit out masses of
+            * data). This means we need to put a new buffer into place after
+            * saving the old generated data to the outData list.
             */
 
            obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp, outSize);
@@ -2905,9 +2906,9 @@ ZlibTransformClose(
                }
            }
        } while (e != Z_STREAM_END);
-       e = deflateEnd(&cd->outStream);
+       (void) deflateEnd(&cd->outStream);
     } else {
-       e = inflateEnd(&cd->inStream);
+       (void) inflateEnd(&cd->inStream);
     }
 
     /*
@@ -3343,10 +3344,13 @@ ZlibTransformGetOption(
                Tcl_DStringAppendElement(dsPtr, "");
            }
        } else {
-           int len;
-           const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len);
+           if (cd->compDictObj) {
+               int len;
+               const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len);
 
-           Tcl_DStringAppend(dsPtr, str, len);
+               Tcl_DStringAppend(dsPtr, str, len);
+           }
+           return TCL_OK;
        }
     }
 
@@ -3548,7 +3552,6 @@ ZlibStackChannelTransform(
     ZlibChannelData *cd = ckalloc(sizeof(ZlibChannelData));
     Tcl_Channel chan;
     int wbits = 0;
-    int e;
 
     if (mode != TCL_ZLIB_STREAM_DEFLATE && mode != TCL_ZLIB_STREAM_INFLATE) {
        Tcl_Panic("unknown mode: %d", mode);
@@ -3602,43 +3605,35 @@ ZlibStackChannelTransform(
      */
 
     if (mode == TCL_ZLIB_STREAM_INFLATE) {
-       e = inflateInit2(&cd->inStream, wbits);
-       if (e != Z_OK) {
+       if (inflateInit2(&cd->inStream, wbits) != Z_OK) {
            goto error;
        }
        cd->inAllocated = DEFAULT_BUFFER_SIZE;
        cd->inBuffer = ckalloc(cd->inAllocated);
        if (cd->flags & IN_HEADER) {
-           e = inflateGetHeader(&cd->inStream, &cd->inHeader.header);
-           if (e != Z_OK) {
+           if (inflateGetHeader(&cd->inStream, &cd->inHeader.header) != Z_OK) {
                goto error;
            }
        }
        if (cd->format == TCL_ZLIB_FORMAT_RAW && cd->compDictObj) {
-           e = SetInflateDictionary(&cd->inStream, cd->compDictObj);
-           if (e != Z_OK) {
+           if (SetInflateDictionary(&cd->inStream, cd->compDictObj) != Z_OK) {
                goto error;
            }
-           TclDecrRefCount(cd->compDictObj);
-           cd->compDictObj = NULL;
        }
     } else {
-       e = deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits,
-               MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-       if (e != Z_OK) {
+       if (deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits,
+               MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) {
            goto error;
        }
        cd->outAllocated = DEFAULT_BUFFER_SIZE;
        cd->outBuffer = ckalloc(cd->outAllocated);
        if (cd->flags & OUT_HEADER) {
-           e = deflateSetHeader(&cd->outStream, &cd->outHeader.header);
-           if (e != Z_OK) {
+           if (deflateSetHeader(&cd->outStream, &cd->outHeader.header) != Z_OK) {
                goto error;
            }
        }
        if (cd->compDictObj) {
-           e = SetDeflateDictionary(&cd->outStream, cd->compDictObj);
-           if (e != Z_OK) {
+           if (SetDeflateDictionary(&cd->outStream, cd->compDictObj) != Z_OK) {
                goto error;
            }
        }
index 9fd2170..9ca4514 100644 (file)
@@ -16,7 +16,7 @@
 if {[info commands package] == ""} {
     error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]"
 }
-package require -exact Tcl 8.6.5
+package require -exact Tcl 8.6.6
 
 # Compute the auto path to use in this interpreter.
 # The values on the path come from several locations:
index 49fd1ac..b1fe234 100755 (executable)
@@ -1,9 +1,9 @@
 if {([info commands ::tcl::pkgconfig] eq "")
        || ([info sharedlibextension] ne ".dll")} return
 if {[::tcl::pkgconfig get debug]} {
-    package ifneeded registry 1.3.1 \
+    package ifneeded registry 1.3.2 \
             [list load [file join $dir tclreg13g.dll] registry]
 } else {
-    package ifneeded registry 1.3.1 \
+    package ifneeded registry 1.3.2 \
             [list load [file join $dir tclreg13.dll] registry]
 }
index 987725f..5ac8823 100644 (file)
@@ -9,4 +9,4 @@
 # full path name of this file's directory.
 
 if {![package vsatisfies [package provide Tcl] 8.5]} {return}
-package ifneeded tcltest 2.3.8 [list source [file join $dir tcltest.tcl]]
+package ifneeded tcltest 2.4.0 [list source [file join $dir tcltest.tcl]]
index 29ef778..cde2660 100644 (file)
@@ -22,7 +22,7 @@ namespace eval tcltest {
     # When the version number changes, be sure to update the pkgIndex.tcl file,
     # and the install directory in the Makefiles.  When the minor version
     # changes (new feature) be sure to update the man page as well.
-    variable Version 2.3.8
+    variable Version 2.4.0
 
     # Compatibility support for dumb variables defined in tcltest 1
     # Do not use these.  Call [package provide Tcl] and [info patchlevel]
@@ -611,16 +611,27 @@ namespace eval tcltest {
 
     proc AcceptVerbose { level } {
        set level [AcceptList $level]
+       set levelMap {
+           l list
+           p pass
+           b body
+           s skip
+           t start
+           e error
+           l line
+           m msec
+           u usec
+       }
+       set levelRegexp "^([join [dict values $levelMap] |])\$"
        if {[llength $level] == 1} {
-           if {![regexp {^(pass|body|skip|start|error|line)$} $level]} {
+           if {![regexp $levelRegexp $level]} {
                # translate single characters abbreviations to expanded list
-               set level [string map {p pass b body s skip t start e error l line} \
-                       [split $level {}]]
+               set level [string map $levelMap [split $level {}]]
            }
        }
        set valid [list]
        foreach v $level {
-           if {[regexp {^(pass|body|skip|start|error|line)$} $v]} {
+           if {[regexp $levelRegexp $v]} {
                lappend valid $v
            }
        }
@@ -1972,6 +1983,11 @@ proc tcltest::test {name description args} {
     # Only run the test body if the setup was successful
     if {!$setupFailure} {
 
+       # Register startup time
+       if {[IsVerbose msec] || [IsVerbose usec]} {
+           set timeStart [clock microseconds]
+       }
+
        # Verbose notification of $body start
        if {[IsVerbose start]} {
            puts [outputChannel] "---- $name start"
@@ -2076,6 +2092,16 @@ proc tcltest::test {name description args} {
        }
     }
 
+    if {[IsVerbose msec] || [IsVerbose usec]} {
+       set t [expr {[clock microseconds] - $timeStart}]
+       if {[IsVerbose usec]} {
+           puts [outputChannel] "++++ $name took $t Î¼s"
+       }
+       if {[IsVerbose msec]} {
+           puts [outputChannel] "++++ $name took [expr {round($t/1000.)}] ms"
+       }
+    }
+
     # if we didn't experience any failures, then we passed
     variable numTests
     if {!($setupFailure || $cleanupFailure || $coreFailure
@@ -2683,7 +2709,7 @@ proc tcltest::GetMatchingDirectories {rootdir} {
        DebugPuts 1 "No test directories remain after applying match\
                and skip patterns!"
     }
-    return $matchDirs
+    return [lsort $matchDirs]
 }
 
 # tcltest::runAllTests --
index 23004bb..3115ee1 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:America/Cambridge_Bay) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-1577923200 -25200 0 MST}
     {-880210800 -21600 1 MWT}
     {-769395600 -21600 1 MPT}
index 2ba87ae..253c4ce 100644 (file)
@@ -6,4 +6,5 @@ set TZData(:America/Caracas) {
     {-1826739140 -16200 0 VET}
     {-157750200 -14400 0 VET}
     {1197183600 -16200 0 VET}
+    {1462086000 -14400 0 VET}
 }
index dd0d151..08f0fd6 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:America/Inuvik) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-536457600 -28800 0 PST}
     {-147888000 -21600 1 PDDT}
     {-131558400 -28800 0 PST}
index 2a2e9fe..ff82866 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:America/Iqaluit) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-865296000 -14400 0 EWT}
     {-769395600 -14400 1 EPT}
     {-765396000 -18000 0 EST}
index 640808e..14d8516 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:America/Pangnirtung) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-1546300800 -14400 0 AST}
     {-880221600 -10800 1 AWT}
     {-769395600 -10800 1 APT}
index f1d7fc4..b8b60d6 100644 (file)
@@ -46,172 +46,4 @@ set TZData(:America/Port-au-Prince) {
     {1414908000 -18000 0 EST}
     {1425798000 -14400 1 EDT}
     {1446357600 -18000 0 EST}
-    {1457852400 -14400 1 EDT}
-    {1478412000 -18000 0 EST}
-    {1489302000 -14400 1 EDT}
-    {1509861600 -18000 0 EST}
-    {1520751600 -14400 1 EDT}
-    {1541311200 -18000 0 EST}
-    {1552201200 -14400 1 EDT}
-    {1572760800 -18000 0 EST}
-    {1583650800 -14400 1 EDT}
-    {1604210400 -18000 0 EST}
-    {1615705200 -14400 1 EDT}
-    {1636264800 -18000 0 EST}
-    {1647154800 -14400 1 EDT}
-    {1667714400 -18000 0 EST}
-    {1678604400 -14400 1 EDT}
-    {1699164000 -18000 0 EST}
-    {1710054000 -14400 1 EDT}
-    {1730613600 -18000 0 EST}
-    {1741503600 -14400 1 EDT}
-    {1762063200 -18000 0 EST}
-    {1772953200 -14400 1 EDT}
-    {1793512800 -18000 0 EST}
-    {1805007600 -14400 1 EDT}
-    {1825567200 -18000 0 EST}
-    {1836457200 -14400 1 EDT}
-    {1857016800 -18000 0 EST}
-    {1867906800 -14400 1 EDT}
-    {1888466400 -18000 0 EST}
-    {1899356400 -14400 1 EDT}
-    {1919916000 -18000 0 EST}
-    {1930806000 -14400 1 EDT}
-    {1951365600 -18000 0 EST}
-    {1962860400 -14400 1 EDT}
-    {1983420000 -18000 0 EST}
-    {1994310000 -14400 1 EDT}
-    {2014869600 -18000 0 EST}
-    {2025759600 -14400 1 EDT}
-    {2046319200 -18000 0 EST}
-    {2057209200 -14400 1 EDT}
-    {2077768800 -18000 0 EST}
-    {2088658800 -14400 1 EDT}
-    {2109218400 -18000 0 EST}
-    {2120108400 -14400 1 EDT}
-    {2140668000 -18000 0 EST}
-    {2152162800 -14400 1 EDT}
-    {2172722400 -18000 0 EST}
-    {2183612400 -14400 1 EDT}
-    {2204172000 -18000 0 EST}
-    {2215062000 -14400 1 EDT}
-    {2235621600 -18000 0 EST}
-    {2246511600 -14400 1 EDT}
-    {2267071200 -18000 0 EST}
-    {2277961200 -14400 1 EDT}
-    {2298520800 -18000 0 EST}
-    {2309410800 -14400 1 EDT}
-    {2329970400 -18000 0 EST}
-    {2341465200 -14400 1 EDT}
-    {2362024800 -18000 0 EST}
-    {2372914800 -14400 1 EDT}
-    {2393474400 -18000 0 EST}
-    {2404364400 -14400 1 EDT}
-    {2424924000 -18000 0 EST}
-    {2435814000 -14400 1 EDT}
-    {2456373600 -18000 0 EST}
-    {2467263600 -14400 1 EDT}
-    {2487823200 -18000 0 EST}
-    {2499318000 -14400 1 EDT}
-    {2519877600 -18000 0 EST}
-    {2530767600 -14400 1 EDT}
-    {2551327200 -18000 0 EST}
-    {2562217200 -14400 1 EDT}
-    {2582776800 -18000 0 EST}
-    {2593666800 -14400 1 EDT}
-    {2614226400 -18000 0 EST}
-    {2625116400 -14400 1 EDT}
-    {2645676000 -18000 0 EST}
-    {2656566000 -14400 1 EDT}
-    {2677125600 -18000 0 EST}
-    {2688620400 -14400 1 EDT}
-    {2709180000 -18000 0 EST}
-    {2720070000 -14400 1 EDT}
-    {2740629600 -18000 0 EST}
-    {2751519600 -14400 1 EDT}
-    {2772079200 -18000 0 EST}
-    {2782969200 -14400 1 EDT}
-    {2803528800 -18000 0 EST}
-    {2814418800 -14400 1 EDT}
-    {2834978400 -18000 0 EST}
-    {2846473200 -14400 1 EDT}
-    {2867032800 -18000 0 EST}
-    {2877922800 -14400 1 EDT}
-    {2898482400 -18000 0 EST}
-    {2909372400 -14400 1 EDT}
-    {2929932000 -18000 0 EST}
-    {2940822000 -14400 1 EDT}
-    {2961381600 -18000 0 EST}
-    {2972271600 -14400 1 EDT}
-    {2992831200 -18000 0 EST}
-    {3003721200 -14400 1 EDT}
-    {3024280800 -18000 0 EST}
-    {3035775600 -14400 1 EDT}
-    {3056335200 -18000 0 EST}
-    {3067225200 -14400 1 EDT}
-    {3087784800 -18000 0 EST}
-    {3098674800 -14400 1 EDT}
-    {3119234400 -18000 0 EST}
-    {3130124400 -14400 1 EDT}
-    {3150684000 -18000 0 EST}
-    {3161574000 -14400 1 EDT}
-    {3182133600 -18000 0 EST}
-    {3193023600 -14400 1 EDT}
-    {3213583200 -18000 0 EST}
-    {3225078000 -14400 1 EDT}
-    {3245637600 -18000 0 EST}
-    {3256527600 -14400 1 EDT}
-    {3277087200 -18000 0 EST}
-    {3287977200 -14400 1 EDT}
-    {3308536800 -18000 0 EST}
-    {3319426800 -14400 1 EDT}
-    {3339986400 -18000 0 EST}
-    {3350876400 -14400 1 EDT}
-    {3371436000 -18000 0 EST}
-    {3382930800 -14400 1 EDT}
-    {3403490400 -18000 0 EST}
-    {3414380400 -14400 1 EDT}
-    {3434940000 -18000 0 EST}
-    {3445830000 -14400 1 EDT}
-    {3466389600 -18000 0 EST}
-    {3477279600 -14400 1 EDT}
-    {3497839200 -18000 0 EST}
-    {3508729200 -14400 1 EDT}
-    {3529288800 -18000 0 EST}
-    {3540178800 -14400 1 EDT}
-    {3560738400 -18000 0 EST}
-    {3572233200 -14400 1 EDT}
-    {3592792800 -18000 0 EST}
-    {3603682800 -14400 1 EDT}
-    {3624242400 -18000 0 EST}
-    {3635132400 -14400 1 EDT}
-    {3655692000 -18000 0 EST}
-    {3666582000 -14400 1 EDT}
-    {3687141600 -18000 0 EST}
-    {3698031600 -14400 1 EDT}
-    {3718591200 -18000 0 EST}
-    {3730086000 -14400 1 EDT}
-    {3750645600 -18000 0 EST}
-    {3761535600 -14400 1 EDT}
-    {3782095200 -18000 0 EST}
-    {3792985200 -14400 1 EDT}
-    {3813544800 -18000 0 EST}
-    {3824434800 -14400 1 EDT}
-    {3844994400 -18000 0 EST}
-    {3855884400 -14400 1 EDT}
-    {3876444000 -18000 0 EST}
-    {3887334000 -14400 1 EDT}
-    {3907893600 -18000 0 EST}
-    {3919388400 -14400 1 EDT}
-    {3939948000 -18000 0 EST}
-    {3950838000 -14400 1 EDT}
-    {3971397600 -18000 0 EST}
-    {3982287600 -14400 1 EDT}
-    {4002847200 -18000 0 EST}
-    {4013737200 -14400 1 EDT}
-    {4034296800 -18000 0 EST}
-    {4045186800 -14400 1 EDT}
-    {4065746400 -18000 0 EST}
-    {4076636400 -14400 1 EDT}
-    {4097196000 -18000 0 EST}
 }
index 770ec5d..9ce9f8d 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:America/Rankin_Inlet) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-410227200 -21600 0 CST}
     {-147895200 -14400 1 CDDT}
     {-131565600 -21600 0 CST}
index b4c0bab..a9881b4 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:America/Resolute) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-704937600 -21600 0 CST}
     {-147895200 -14400 1 CDDT}
     {-131565600 -21600 0 CST}
index b6d9b38..3a5c0fd 100644 (file)
@@ -118,5 +118,172 @@ set TZData(:America/Santiago) {
     {1378612800 -10800 1 CLST}
     {1398567600 -14400 0 CLT}
     {1410062400 -10800 1 CLST}
-    {1430017200 -10800 0 CLT}
+    {1463281200 -14400 0 CLT}
+    {1471147200 -10800 1 CLST}
+    {1494730800 -14400 0 CLT}
+    {1502596800 -10800 1 CLST}
+    {1526180400 -14400 0 CLT}
+    {1534046400 -10800 1 CLST}
+    {1557630000 -14400 0 CLT}
+    {1565496000 -10800 1 CLST}
+    {1589079600 -14400 0 CLT}
+    {1596945600 -10800 1 CLST}
+    {1620529200 -14400 0 CLT}
+    {1629000000 -10800 1 CLST}
+    {1652583600 -14400 0 CLT}
+    {1660449600 -10800 1 CLST}
+    {1684033200 -14400 0 CLT}
+    {1691899200 -10800 1 CLST}
+    {1715482800 -14400 0 CLT}
+    {1723348800 -10800 1 CLST}
+    {1746932400 -14400 0 CLT}
+    {1754798400 -10800 1 CLST}
+    {1778382000 -14400 0 CLT}
+    {1786248000 -10800 1 CLST}
+    {1809831600 -14400 0 CLT}
+    {1818302400 -10800 1 CLST}
+    {1841886000 -14400 0 CLT}
+    {1849752000 -10800 1 CLST}
+    {1873335600 -14400 0 CLT}
+    {1881201600 -10800 1 CLST}
+    {1904785200 -14400 0 CLT}
+    {1912651200 -10800 1 CLST}
+    {1936234800 -14400 0 CLT}
+    {1944100800 -10800 1 CLST}
+    {1967684400 -14400 0 CLT}
+    {1976155200 -10800 1 CLST}
+    {1999738800 -14400 0 CLT}
+    {2007604800 -10800 1 CLST}
+    {2031188400 -14400 0 CLT}
+    {2039054400 -10800 1 CLST}
+    {2062638000 -14400 0 CLT}
+    {2070504000 -10800 1 CLST}
+    {2094087600 -14400 0 CLT}
+    {2101953600 -10800 1 CLST}
+    {2125537200 -14400 0 CLT}
+    {2133403200 -10800 1 CLST}
+    {2156986800 -14400 0 CLT}
+    {2165457600 -10800 1 CLST}
+    {2189041200 -14400 0 CLT}
+    {2196907200 -10800 1 CLST}
+    {2220490800 -14400 0 CLT}
+    {2228356800 -10800 1 CLST}
+    {2251940400 -14400 0 CLT}
+    {2259806400 -10800 1 CLST}
+    {2283390000 -14400 0 CLT}
+    {2291256000 -10800 1 CLST}
+    {2314839600 -14400 0 CLT}
+    {2322705600 -10800 1 CLST}
+    {2346894000 -14400 0 CLT}
+    {2354760000 -10800 1 CLST}
+    {2378343600 -14400 0 CLT}
+    {2386209600 -10800 1 CLST}
+    {2409793200 -14400 0 CLT}
+    {2417659200 -10800 1 CLST}
+    {2441242800 -14400 0 CLT}
+    {2449108800 -10800 1 CLST}
+    {2472692400 -14400 0 CLT}
+    {2480558400 -10800 1 CLST}
+    {2504142000 -14400 0 CLT}
+    {2512612800 -10800 1 CLST}
+    {2536196400 -14400 0 CLT}
+    {2544062400 -10800 1 CLST}
+    {2567646000 -14400 0 CLT}
+    {2575512000 -10800 1 CLST}
+    {2599095600 -14400 0 CLT}
+    {2606961600 -10800 1 CLST}
+    {2630545200 -14400 0 CLT}
+    {2638411200 -10800 1 CLST}
+    {2661994800 -14400 0 CLT}
+    {2669860800 -10800 1 CLST}
+    {2693444400 -14400 0 CLT}
+    {2701915200 -10800 1 CLST}
+    {2725498800 -14400 0 CLT}
+    {2733364800 -10800 1 CLST}
+    {2756948400 -14400 0 CLT}
+    {2764814400 -10800 1 CLST}
+    {2788398000 -14400 0 CLT}
+    {2796264000 -10800 1 CLST}
+    {2819847600 -14400 0 CLT}
+    {2827713600 -10800 1 CLST}
+    {2851297200 -14400 0 CLT}
+    {2859768000 -10800 1 CLST}
+    {2883351600 -14400 0 CLT}
+    {2891217600 -10800 1 CLST}
+    {2914801200 -14400 0 CLT}
+    {2922667200 -10800 1 CLST}
+    {2946250800 -14400 0 CLT}
+    {2954116800 -10800 1 CLST}
+    {2977700400 -14400 0 CLT}
+    {2985566400 -10800 1 CLST}
+    {3009150000 -14400 0 CLT}
+    {3017016000 -10800 1 CLST}
+    {3040599600 -14400 0 CLT}
+    {3049070400 -10800 1 CLST}
+    {3072654000 -14400 0 CLT}
+    {3080520000 -10800 1 CLST}
+    {3104103600 -14400 0 CLT}
+    {3111969600 -10800 1 CLST}
+    {3135553200 -14400 0 CLT}
+    {3143419200 -10800 1 CLST}
+    {3167002800 -14400 0 CLT}
+    {3174868800 -10800 1 CLST}
+    {3198452400 -14400 0 CLT}
+    {3206318400 -10800 1 CLST}
+    {3230506800 -14400 0 CLT}
+    {3238372800 -10800 1 CLST}
+    {3261956400 -14400 0 CLT}
+    {3269822400 -10800 1 CLST}
+    {3293406000 -14400 0 CLT}
+    {3301272000 -10800 1 CLST}
+    {3324855600 -14400 0 CLT}
+    {3332721600 -10800 1 CLST}
+    {3356305200 -14400 0 CLT}
+    {3364171200 -10800 1 CLST}
+    {3387754800 -14400 0 CLT}
+    {3396225600 -10800 1 CLST}
+    {3419809200 -14400 0 CLT}
+    {3427675200 -10800 1 CLST}
+    {3451258800 -14400 0 CLT}
+    {3459124800 -10800 1 CLST}
+    {3482708400 -14400 0 CLT}
+    {3490574400 -10800 1 CLST}
+    {3514158000 -14400 0 CLT}
+    {3522024000 -10800 1 CLST}
+    {3545607600 -14400 0 CLT}
+    {3553473600 -10800 1 CLST}
+    {3577057200 -14400 0 CLT}
+    {3585528000 -10800 1 CLST}
+    {3609111600 -14400 0 CLT}
+    {3616977600 -10800 1 CLST}
+    {3640561200 -14400 0 CLT}
+    {3648427200 -10800 1 CLST}
+    {3672010800 -14400 0 CLT}
+    {3679876800 -10800 1 CLST}
+    {3703460400 -14400 0 CLT}
+    {3711326400 -10800 1 CLST}
+    {3734910000 -14400 0 CLT}
+    {3743380800 -10800 1 CLST}
+    {3766964400 -14400 0 CLT}
+    {3774830400 -10800 1 CLST}
+    {3798414000 -14400 0 CLT}
+    {3806280000 -10800 1 CLST}
+    {3829863600 -14400 0 CLT}
+    {3837729600 -10800 1 CLST}
+    {3861313200 -14400 0 CLT}
+    {3869179200 -10800 1 CLST}
+    {3892762800 -14400 0 CLT}
+    {3900628800 -10800 1 CLST}
+    {3924212400 -14400 0 CLT}
+    {3932683200 -10800 1 CLST}
+    {3956266800 -14400 0 CLT}
+    {3964132800 -10800 1 CLST}
+    {3987716400 -14400 0 CLT}
+    {3995582400 -10800 1 CLST}
+    {4019166000 -14400 0 CLT}
+    {4027032000 -10800 1 CLST}
+    {4050615600 -14400 0 CLT}
+    {4058481600 -10800 1 CLST}
+    {4082065200 -14400 0 CLT}
+    {4089931200 -10800 1 CLST}
 }
index 44ca658..c6c4ed5 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:America/Yellowknife) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-1104537600 -25200 0 MST}
     {-880210800 -21600 1 MWT}
     {-769395600 -21600 1 MPT}
index 56d5df7..2573dac 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Casey) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-31536000 28800 0 AWST}
     {1255802400 39600 0 CAST}
     {1267714800 28800 0 AWST}
index 2762d2f..c98be2f 100644 (file)
@@ -1,9 +1,9 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Davis) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-409190400 25200 0 DAVT}
-    {-163062000 0 0 zzz}
+    {-163062000 0 0 -00}
     {-28857600 25200 0 DAVT}
     {1255806000 18000 0 DAVT}
     {1268251200 25200 0 DAVT}
index 41dc1e3..8d21d45 100644 (file)
@@ -1,8 +1,8 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/DumontDUrville) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-725846400 36000 0 PMT}
-    {-566992800 0 0 zzz}
+    {-566992800 0 0 -00}
     {-415497600 36000 0 DDUT}
 }
index 07ddff6..9ed0630 100644 (file)
@@ -1,12 +1,12 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Macquarie) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-2214259200 36000 0 AEST}
     {-1680508800 39600 1 AEDT}
     {-1669892400 39600 0 AEDT}
     {-1665392400 36000 0 AEST}
-    {-1601719200 0 0 zzz}
+    {-1601719200 0 0 -00}
     {-94730400 36000 0 AEST}
     {-71136000 39600 1 AEDT}
     {-55411200 36000 0 AEST}
index ba03ba1..e50aa07 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Mawson) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-501206400 21600 0 MAWT}
     {1255809600 18000 0 MAWT}
 }
index 2c43861..62b17e1 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Palmer) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-157766400 -14400 0 ART}
     {-152654400 -14400 0 ART}
     {-132955200 -10800 1 ARST}
@@ -81,5 +81,172 @@ set TZData(:Antarctica/Palmer) {
     {1378612800 -10800 1 CLST}
     {1398567600 -14400 0 CLT}
     {1410062400 -10800 1 CLST}
-    {1430017200 -10800 0 CLT}
+    {1463281200 -14400 0 CLT}
+    {1471147200 -10800 1 CLST}
+    {1494730800 -14400 0 CLT}
+    {1502596800 -10800 1 CLST}
+    {1526180400 -14400 0 CLT}
+    {1534046400 -10800 1 CLST}
+    {1557630000 -14400 0 CLT}
+    {1565496000 -10800 1 CLST}
+    {1589079600 -14400 0 CLT}
+    {1596945600 -10800 1 CLST}
+    {1620529200 -14400 0 CLT}
+    {1629000000 -10800 1 CLST}
+    {1652583600 -14400 0 CLT}
+    {1660449600 -10800 1 CLST}
+    {1684033200 -14400 0 CLT}
+    {1691899200 -10800 1 CLST}
+    {1715482800 -14400 0 CLT}
+    {1723348800 -10800 1 CLST}
+    {1746932400 -14400 0 CLT}
+    {1754798400 -10800 1 CLST}
+    {1778382000 -14400 0 CLT}
+    {1786248000 -10800 1 CLST}
+    {1809831600 -14400 0 CLT}
+    {1818302400 -10800 1 CLST}
+    {1841886000 -14400 0 CLT}
+    {1849752000 -10800 1 CLST}
+    {1873335600 -14400 0 CLT}
+    {1881201600 -10800 1 CLST}
+    {1904785200 -14400 0 CLT}
+    {1912651200 -10800 1 CLST}
+    {1936234800 -14400 0 CLT}
+    {1944100800 -10800 1 CLST}
+    {1967684400 -14400 0 CLT}
+    {1976155200 -10800 1 CLST}
+    {1999738800 -14400 0 CLT}
+    {2007604800 -10800 1 CLST}
+    {2031188400 -14400 0 CLT}
+    {2039054400 -10800 1 CLST}
+    {2062638000 -14400 0 CLT}
+    {2070504000 -10800 1 CLST}
+    {2094087600 -14400 0 CLT}
+    {2101953600 -10800 1 CLST}
+    {2125537200 -14400 0 CLT}
+    {2133403200 -10800 1 CLST}
+    {2156986800 -14400 0 CLT}
+    {2165457600 -10800 1 CLST}
+    {2189041200 -14400 0 CLT}
+    {2196907200 -10800 1 CLST}
+    {2220490800 -14400 0 CLT}
+    {2228356800 -10800 1 CLST}
+    {2251940400 -14400 0 CLT}
+    {2259806400 -10800 1 CLST}
+    {2283390000 -14400 0 CLT}
+    {2291256000 -10800 1 CLST}
+    {2314839600 -14400 0 CLT}
+    {2322705600 -10800 1 CLST}
+    {2346894000 -14400 0 CLT}
+    {2354760000 -10800 1 CLST}
+    {2378343600 -14400 0 CLT}
+    {2386209600 -10800 1 CLST}
+    {2409793200 -14400 0 CLT}
+    {2417659200 -10800 1 CLST}
+    {2441242800 -14400 0 CLT}
+    {2449108800 -10800 1 CLST}
+    {2472692400 -14400 0 CLT}
+    {2480558400 -10800 1 CLST}
+    {2504142000 -14400 0 CLT}
+    {2512612800 -10800 1 CLST}
+    {2536196400 -14400 0 CLT}
+    {2544062400 -10800 1 CLST}
+    {2567646000 -14400 0 CLT}
+    {2575512000 -10800 1 CLST}
+    {2599095600 -14400 0 CLT}
+    {2606961600 -10800 1 CLST}
+    {2630545200 -14400 0 CLT}
+    {2638411200 -10800 1 CLST}
+    {2661994800 -14400 0 CLT}
+    {2669860800 -10800 1 CLST}
+    {2693444400 -14400 0 CLT}
+    {2701915200 -10800 1 CLST}
+    {2725498800 -14400 0 CLT}
+    {2733364800 -10800 1 CLST}
+    {2756948400 -14400 0 CLT}
+    {2764814400 -10800 1 CLST}
+    {2788398000 -14400 0 CLT}
+    {2796264000 -10800 1 CLST}
+    {2819847600 -14400 0 CLT}
+    {2827713600 -10800 1 CLST}
+    {2851297200 -14400 0 CLT}
+    {2859768000 -10800 1 CLST}
+    {2883351600 -14400 0 CLT}
+    {2891217600 -10800 1 CLST}
+    {2914801200 -14400 0 CLT}
+    {2922667200 -10800 1 CLST}
+    {2946250800 -14400 0 CLT}
+    {2954116800 -10800 1 CLST}
+    {2977700400 -14400 0 CLT}
+    {2985566400 -10800 1 CLST}
+    {3009150000 -14400 0 CLT}
+    {3017016000 -10800 1 CLST}
+    {3040599600 -14400 0 CLT}
+    {3049070400 -10800 1 CLST}
+    {3072654000 -14400 0 CLT}
+    {3080520000 -10800 1 CLST}
+    {3104103600 -14400 0 CLT}
+    {3111969600 -10800 1 CLST}
+    {3135553200 -14400 0 CLT}
+    {3143419200 -10800 1 CLST}
+    {3167002800 -14400 0 CLT}
+    {3174868800 -10800 1 CLST}
+    {3198452400 -14400 0 CLT}
+    {3206318400 -10800 1 CLST}
+    {3230506800 -14400 0 CLT}
+    {3238372800 -10800 1 CLST}
+    {3261956400 -14400 0 CLT}
+    {3269822400 -10800 1 CLST}
+    {3293406000 -14400 0 CLT}
+    {3301272000 -10800 1 CLST}
+    {3324855600 -14400 0 CLT}
+    {3332721600 -10800 1 CLST}
+    {3356305200 -14400 0 CLT}
+    {3364171200 -10800 1 CLST}
+    {3387754800 -14400 0 CLT}
+    {3396225600 -10800 1 CLST}
+    {3419809200 -14400 0 CLT}
+    {3427675200 -10800 1 CLST}
+    {3451258800 -14400 0 CLT}
+    {3459124800 -10800 1 CLST}
+    {3482708400 -14400 0 CLT}
+    {3490574400 -10800 1 CLST}
+    {3514158000 -14400 0 CLT}
+    {3522024000 -10800 1 CLST}
+    {3545607600 -14400 0 CLT}
+    {3553473600 -10800 1 CLST}
+    {3577057200 -14400 0 CLT}
+    {3585528000 -10800 1 CLST}
+    {3609111600 -14400 0 CLT}
+    {3616977600 -10800 1 CLST}
+    {3640561200 -14400 0 CLT}
+    {3648427200 -10800 1 CLST}
+    {3672010800 -14400 0 CLT}
+    {3679876800 -10800 1 CLST}
+    {3703460400 -14400 0 CLT}
+    {3711326400 -10800 1 CLST}
+    {3734910000 -14400 0 CLT}
+    {3743380800 -10800 1 CLST}
+    {3766964400 -14400 0 CLT}
+    {3774830400 -10800 1 CLST}
+    {3798414000 -14400 0 CLT}
+    {3806280000 -10800 1 CLST}
+    {3829863600 -14400 0 CLT}
+    {3837729600 -10800 1 CLST}
+    {3861313200 -14400 0 CLT}
+    {3869179200 -10800 1 CLST}
+    {3892762800 -14400 0 CLT}
+    {3900628800 -10800 1 CLST}
+    {3924212400 -14400 0 CLT}
+    {3932683200 -10800 1 CLST}
+    {3956266800 -14400 0 CLT}
+    {3964132800 -10800 1 CLST}
+    {3987716400 -14400 0 CLT}
+    {3995582400 -10800 1 CLST}
+    {4019166000 -14400 0 CLT}
+    {4027032000 -10800 1 CLST}
+    {4050615600 -14400 0 CLT}
+    {4058481600 -10800 1 CLST}
+    {4082065200 -14400 0 CLT}
+    {4089931200 -10800 1 CLST}
 }
index 24d7f3e..3a219c7 100644 (file)
@@ -1,6 +1,6 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Rothera) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {218246400 -10800 0 ROTT}
 }
index 4d046b5..1fe030a 100644 (file)
@@ -1,6 +1,6 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Syowa) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-407808000 10800 0 SYOT}
 }
index 7d2b042..09727a8 100644 (file)
@@ -1,7 +1,7 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Troll) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {1108166400 0 0 UTC}
     {1111885200 7200 1 CEST}
     {1130634000 0 0 UTC}
index f846f65..a59868b 100644 (file)
@@ -1,6 +1,6 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Antarctica/Vostok) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-380073600 21600 0 VOST}
 }
index 68dee29..2b83197 100644 (file)
@@ -2,55 +2,56 @@
 
 set TZData(:Asia/Almaty) {
     {-9223372036854775808 18468 0 LMT}
-    {-1441170468 18000 0 ALMT}
-    {-1247547600 21600 0 ALMT}
-    {354909600 25200 1 ALMST}
-    {370717200 21600 0 ALMT}
-    {386445600 25200 1 ALMST}
-    {402253200 21600 0 ALMT}
-    {417981600 25200 1 ALMST}
-    {433789200 21600 0 ALMT}
-    {449604000 25200 1 ALMST}
-    {465336000 21600 0 ALMT}
-    {481060800 25200 1 ALMST}
-    {496785600 21600 0 ALMT}
-    {512510400 25200 1 ALMST}
-    {528235200 21600 0 ALMT}
-    {543960000 25200 1 ALMST}
-    {559684800 21600 0 ALMT}
-    {575409600 25200 1 ALMST}
-    {591134400 21600 0 ALMT}
-    {606859200 25200 1 ALMST}
-    {622584000 21600 0 ALMT}
-    {638308800 25200 1 ALMST}
-    {654638400 21600 0 ALMT}
-    {662666400 21600 0 ALMT}
-    {694202400 21600 0 ALMT}
-    {701802000 25200 1 ALMST}
-    {717523200 21600 0 ALMT}
-    {733262400 25200 1 ALMST}
-    {748987200 21600 0 ALMT}
-    {764712000 25200 1 ALMST}
-    {780436800 21600 0 ALMT}
-    {796161600 25200 1 ALMST}
-    {811886400 21600 0 ALMT}
-    {828216000 25200 1 ALMST}
-    {846360000 21600 0 ALMT}
-    {859665600 25200 1 ALMST}
-    {877809600 21600 0 ALMT}
-    {891115200 25200 1 ALMST}
-    {909259200 21600 0 ALMT}
-    {922564800 25200 1 ALMST}
-    {941313600 21600 0 ALMT}
-    {954014400 25200 1 ALMST}
-    {972763200 21600 0 ALMT}
-    {985464000 25200 1 ALMST}
-    {1004212800 21600 0 ALMT}
-    {1017518400 25200 1 ALMST}
-    {1035662400 21600 0 ALMT}
-    {1048968000 25200 1 ALMST}
-    {1067112000 21600 0 ALMT}
-    {1080417600 25200 1 ALMST}
-    {1099166400 21600 0 ALMT}
-    {1110823200 21600 0 ALMT}
+    {-1441170468 18000 0 +05}
+    {-1247547600 21600 0 +06}
+    {354909600 25200 1 +07}
+    {370717200 21600 0 +06}
+    {386445600 25200 1 +07}
+    {402253200 21600 0 +06}
+    {417981600 25200 1 +07}
+    {433789200 21600 0 +06}
+    {449604000 25200 1 +07}
+    {465336000 21600 0 +06}
+    {481060800 25200 1 +07}
+    {496785600 21600 0 +06}
+    {512510400 25200 1 +07}
+    {528235200 21600 0 +06}
+    {543960000 25200 1 +07}
+    {559684800 21600 0 +06}
+    {575409600 25200 1 +07}
+    {591134400 21600 0 +06}
+    {606859200 25200 1 +07}
+    {622584000 21600 0 +06}
+    {638308800 25200 1 +07}
+    {654638400 21600 0 +06}
+    {670363200 18000 0 +05}
+    {670366800 21600 1 +06}
+    {686091600 18000 0 +05}
+    {695768400 21600 0 +06}
+    {701812800 25200 1 +07}
+    {717537600 21600 0 +06}
+    {733262400 25200 1 +07}
+    {748987200 21600 0 +06}
+    {764712000 25200 1 +07}
+    {780436800 21600 0 +06}
+    {796161600 25200 1 +07}
+    {811886400 21600 0 +06}
+    {828216000 25200 1 +07}
+    {846360000 21600 0 +06}
+    {859665600 25200 1 +07}
+    {877809600 21600 0 +06}
+    {891115200 25200 1 +07}
+    {909259200 21600 0 +06}
+    {922564800 25200 1 +07}
+    {941313600 21600 0 +06}
+    {954014400 25200 1 +07}
+    {972763200 21600 0 +06}
+    {985464000 25200 1 +07}
+    {1004212800 21600 0 +06}
+    {1017518400 25200 1 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
 }
index 50ace50..2e8ffc7 100644 (file)
@@ -29,8 +29,8 @@ set TZData(:Asia/Anadyr) {
     {670345200 43200 1 ANAST}
     {686070000 39600 0 ANAT}
     {695746800 43200 0 ANAMMTT}
-    {701780400 46800 1 ANAST}
-    {717501600 43200 0 ANAT}
+    {701791200 46800 1 ANAST}
+    {717516000 43200 0 ANAT}
     {733240800 46800 1 ANAST}
     {748965600 43200 0 ANAT}
     {764690400 46800 1 ANAST}
index 11e89a2..90cc94d 100644 (file)
@@ -2,57 +2,58 @@
 
 set TZData(:Asia/Aqtau) {
     {-9223372036854775808 12064 0 LMT}
-    {-1441164064 14400 0 FORT}
-    {-1247544000 18000 0 FORT}
-    {-220942800 18000 0 SHET}
-    {370724400 21600 0 SHET}
-    {386445600 18000 0 SHET}
-    {386449200 21600 1 SHEST}
-    {402256800 18000 0 SHET}
-    {417985200 21600 1 SHEST}
-    {433792800 18000 0 SHET}
-    {449607600 21600 1 SHEST}
-    {465339600 18000 0 SHET}
-    {481064400 21600 1 SHEST}
-    {496789200 18000 0 SHET}
-    {512514000 21600 1 SHEST}
-    {528238800 18000 0 SHET}
-    {543963600 21600 1 SHEST}
-    {559688400 18000 0 SHET}
-    {575413200 21600 1 SHEST}
-    {591138000 18000 0 SHET}
-    {606862800 21600 1 SHEST}
-    {622587600 18000 0 SHET}
-    {638312400 21600 1 SHEST}
-    {654642000 18000 0 SHET}
-    {662670000 18000 0 SHET}
-    {692823600 18000 0 AQTT}
-    {701805600 21600 1 AQTST}
-    {717526800 18000 0 AQTT}
-    {733266000 21600 1 AQTST}
-    {748990800 18000 0 AQTT}
-    {764715600 21600 1 AQTST}
-    {780440400 18000 0 AQTT}
-    {796165200 14400 0 AQTT}
-    {796168800 18000 1 AQTST}
-    {811893600 14400 0 AQTT}
-    {828223200 18000 1 AQTST}
-    {846367200 14400 0 AQTT}
-    {859672800 18000 1 AQTST}
-    {877816800 14400 0 AQTT}
-    {891122400 18000 1 AQTST}
-    {909266400 14400 0 AQTT}
-    {922572000 18000 1 AQTST}
-    {941320800 14400 0 AQTT}
-    {954021600 18000 1 AQTST}
-    {972770400 14400 0 AQTT}
-    {985471200 18000 1 AQTST}
-    {1004220000 14400 0 AQTT}
-    {1017525600 18000 1 AQTST}
-    {1035669600 14400 0 AQTT}
-    {1048975200 18000 1 AQTST}
-    {1067119200 14400 0 AQTT}
-    {1080424800 18000 1 AQTST}
-    {1099173600 14400 0 AQTT}
-    {1110830400 18000 0 AQTT}
+    {-1441164064 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {-220942800 18000 0 +05}
+    {370724400 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 21600 1 +06}
+    {622587600 18000 0 +05}
+    {638312400 21600 1 +06}
+    {654642000 18000 0 +05}
+    {670366800 14400 0 +04}
+    {670370400 18000 1 +05}
+    {686095200 14400 0 +04}
+    {695772000 18000 0 +05}
+    {701816400 21600 1 +06}
+    {717541200 18000 0 +05}
+    {733266000 21600 1 +06}
+    {748990800 18000 0 +05}
+    {764715600 21600 1 +06}
+    {780440400 18000 0 +05}
+    {780444000 14400 0 +04}
+    {796168800 18000 1 +05}
+    {811893600 14400 0 +04}
+    {828223200 18000 1 +05}
+    {846367200 14400 0 +04}
+    {859672800 18000 1 +05}
+    {877816800 14400 0 +04}
+    {891122400 18000 1 +05}
+    {909266400 14400 0 +04}
+    {922572000 18000 1 +05}
+    {941320800 14400 0 +04}
+    {954021600 18000 1 +05}
+    {972770400 14400 0 +04}
+    {985471200 18000 1 +05}
+    {1004220000 14400 0 +04}
+    {1017525600 18000 1 +05}
+    {1035669600 14400 0 +04}
+    {1048975200 18000 1 +05}
+    {1067119200 14400 0 +04}
+    {1080424800 18000 1 +05}
+    {1099173600 18000 0 +05}
 }
index c857491..55ef556 100644 (file)
@@ -2,56 +2,57 @@
 
 set TZData(:Asia/Aqtobe) {
     {-9223372036854775808 13720 0 LMT}
-    {-1441165720 14400 0 AKTT}
-    {-1247544000 18000 0 AKTT}
-    {354913200 21600 1 AKTST}
-    {370720800 21600 0 AKTT}
-    {386445600 18000 0 AKTT}
-    {386449200 21600 1 AKTST}
-    {402256800 18000 0 AKTT}
-    {417985200 21600 1 AKTST}
-    {433792800 18000 0 AKTT}
-    {449607600 21600 1 AKTST}
-    {465339600 18000 0 AKTT}
-    {481064400 21600 1 AKTST}
-    {496789200 18000 0 AKTT}
-    {512514000 21600 1 AKTST}
-    {528238800 18000 0 AKTT}
-    {543963600 21600 1 AKTST}
-    {559688400 18000 0 AKTT}
-    {575413200 21600 1 AKTST}
-    {591138000 18000 0 AKTT}
-    {606862800 21600 1 AKTST}
-    {622587600 18000 0 AKTT}
-    {638312400 21600 1 AKTST}
-    {654642000 18000 0 AKTT}
-    {662670000 18000 0 AKTT}
-    {692823600 18000 0 AQTT}
-    {701805600 21600 1 AQTST}
-    {717526800 18000 0 AQTT}
-    {733266000 21600 1 AQTST}
-    {748990800 18000 0 AQTT}
-    {764715600 21600 1 AQTST}
-    {780440400 18000 0 AQTT}
-    {796165200 21600 1 AQTST}
-    {811890000 18000 0 AQTT}
-    {828219600 21600 1 AQTST}
-    {846363600 18000 0 AQTT}
-    {859669200 21600 1 AQTST}
-    {877813200 18000 0 AQTT}
-    {891118800 21600 1 AQTST}
-    {909262800 18000 0 AQTT}
-    {922568400 21600 1 AQTST}
-    {941317200 18000 0 AQTT}
-    {954018000 21600 1 AQTST}
-    {972766800 18000 0 AQTT}
-    {985467600 21600 1 AQTST}
-    {1004216400 18000 0 AQTT}
-    {1017522000 21600 1 AQTST}
-    {1035666000 18000 0 AQTT}
-    {1048971600 21600 1 AQTST}
-    {1067115600 18000 0 AQTT}
-    {1080421200 21600 1 AQTST}
-    {1099170000 18000 0 AQTT}
-    {1110826800 18000 0 AQTT}
+    {-1441165720 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {354913200 21600 1 +06}
+    {370720800 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 21600 1 +06}
+    {622587600 18000 0 +05}
+    {638312400 21600 1 +06}
+    {654642000 18000 0 +05}
+    {670366800 14400 0 +04}
+    {670370400 18000 1 +05}
+    {686095200 14400 0 +04}
+    {695772000 18000 0 +05}
+    {701816400 21600 1 +06}
+    {717541200 18000 0 +05}
+    {733266000 21600 1 +06}
+    {748990800 18000 0 +05}
+    {764715600 21600 1 +06}
+    {780440400 18000 0 +05}
+    {796165200 21600 1 +06}
+    {811890000 18000 0 +05}
+    {828219600 21600 1 +06}
+    {846363600 18000 0 +05}
+    {859669200 21600 1 +06}
+    {877813200 18000 0 +05}
+    {891118800 21600 1 +06}
+    {909262800 18000 0 +05}
+    {922568400 21600 1 +06}
+    {941317200 18000 0 +05}
+    {954018000 21600 1 +06}
+    {972766800 18000 0 +05}
+    {985467600 21600 1 +06}
+    {1004216400 18000 0 +05}
+    {1017522000 21600 1 +06}
+    {1035666000 18000 0 +05}
+    {1048971600 21600 1 +06}
+    {1067115600 18000 0 +05}
+    {1080421200 21600 1 +06}
+    {1099170000 18000 0 +05}
 }
index e50071b..e9ee835 100644 (file)
@@ -27,8 +27,8 @@ set TZData(:Asia/Baku) {
     {670370400 14400 1 BAKST}
     {683496000 14400 0 AZST}
     {686098800 10800 0 AZT}
-    {701812800 14400 1 AZST}
-    {717537600 14400 0 AZT}
+    {701823600 14400 1 AZST}
+    {717548400 14400 0 AZT}
     {820440000 14400 0 AZT}
     {828234000 18000 1 AZST}
     {846378000 14400 0 AZT}
@@ -71,172 +71,4 @@ set TZData(:Asia/Baku) {
     {1414281600 14400 0 AZT}
     {1427587200 18000 1 AZST}
     {1445731200 14400 0 AZT}
-    {1459036800 18000 1 AZST}
-    {1477785600 14400 0 AZT}
-    {1490486400 18000 1 AZST}
-    {1509235200 14400 0 AZT}
-    {1521936000 18000 1 AZST}
-    {1540684800 14400 0 AZT}
-    {1553990400 18000 1 AZST}
-    {1572134400 14400 0 AZT}
-    {1585440000 18000 1 AZST}
-    {1603584000 14400 0 AZT}
-    {1616889600 18000 1 AZST}
-    {1635638400 14400 0 AZT}
-    {1648339200 18000 1 AZST}
-    {1667088000 14400 0 AZT}
-    {1679788800 18000 1 AZST}
-    {1698537600 14400 0 AZT}
-    {1711843200 18000 1 AZST}
-    {1729987200 14400 0 AZT}
-    {1743292800 18000 1 AZST}
-    {1761436800 14400 0 AZT}
-    {1774742400 18000 1 AZST}
-    {1792886400 14400 0 AZT}
-    {1806192000 18000 1 AZST}
-    {1824940800 14400 0 AZT}
-    {1837641600 18000 1 AZST}
-    {1856390400 14400 0 AZT}
-    {1869091200 18000 1 AZST}
-    {1887840000 14400 0 AZT}
-    {1901145600 18000 1 AZST}
-    {1919289600 14400 0 AZT}
-    {1932595200 18000 1 AZST}
-    {1950739200 14400 0 AZT}
-    {1964044800 18000 1 AZST}
-    {1982793600 14400 0 AZT}
-    {1995494400 18000 1 AZST}
-    {2014243200 14400 0 AZT}
-    {2026944000 18000 1 AZST}
-    {2045692800 14400 0 AZT}
-    {2058393600 18000 1 AZST}
-    {2077142400 14400 0 AZT}
-    {2090448000 18000 1 AZST}
-    {2108592000 14400 0 AZT}
-    {2121897600 18000 1 AZST}
-    {2140041600 14400 0 AZT}
-    {2153347200 18000 1 AZST}
-    {2172096000 14400 0 AZT}
-    {2184796800 18000 1 AZST}
-    {2203545600 14400 0 AZT}
-    {2216246400 18000 1 AZST}
-    {2234995200 14400 0 AZT}
-    {2248300800 18000 1 AZST}
-    {2266444800 14400 0 AZT}
-    {2279750400 18000 1 AZST}
-    {2297894400 14400 0 AZT}
-    {2311200000 18000 1 AZST}
-    {2329344000 14400 0 AZT}
-    {2342649600 18000 1 AZST}
-    {2361398400 14400 0 AZT}
-    {2374099200 18000 1 AZST}
-    {2392848000 14400 0 AZT}
-    {2405548800 18000 1 AZST}
-    {2424297600 14400 0 AZT}
-    {2437603200 18000 1 AZST}
-    {2455747200 14400 0 AZT}
-    {2469052800 18000 1 AZST}
-    {2487196800 14400 0 AZT}
-    {2500502400 18000 1 AZST}
-    {2519251200 14400 0 AZT}
-    {2531952000 18000 1 AZST}
-    {2550700800 14400 0 AZT}
-    {2563401600 18000 1 AZST}
-    {2582150400 14400 0 AZT}
-    {2595456000 18000 1 AZST}
-    {2613600000 14400 0 AZT}
-    {2626905600 18000 1 AZST}
-    {2645049600 14400 0 AZT}
-    {2658355200 18000 1 AZST}
-    {2676499200 14400 0 AZT}
-    {2689804800 18000 1 AZST}
-    {2708553600 14400 0 AZT}
-    {2721254400 18000 1 AZST}
-    {2740003200 14400 0 AZT}
-    {2752704000 18000 1 AZST}
-    {2771452800 14400 0 AZT}
-    {2784758400 18000 1 AZST}
-    {2802902400 14400 0 AZT}
-    {2816208000 18000 1 AZST}
-    {2834352000 14400 0 AZT}
-    {2847657600 18000 1 AZST}
-    {2866406400 14400 0 AZT}
-    {2879107200 18000 1 AZST}
-    {2897856000 14400 0 AZT}
-    {2910556800 18000 1 AZST}
-    {2929305600 14400 0 AZT}
-    {2942006400 18000 1 AZST}
-    {2960755200 14400 0 AZT}
-    {2974060800 18000 1 AZST}
-    {2992204800 14400 0 AZT}
-    {3005510400 18000 1 AZST}
-    {3023654400 14400 0 AZT}
-    {3036960000 18000 1 AZST}
-    {3055708800 14400 0 AZT}
-    {3068409600 18000 1 AZST}
-    {3087158400 14400 0 AZT}
-    {3099859200 18000 1 AZST}
-    {3118608000 14400 0 AZT}
-    {3131913600 18000 1 AZST}
-    {3150057600 14400 0 AZT}
-    {3163363200 18000 1 AZST}
-    {3181507200 14400 0 AZT}
-    {3194812800 18000 1 AZST}
-    {3212956800 14400 0 AZT}
-    {3226262400 18000 1 AZST}
-    {3245011200 14400 0 AZT}
-    {3257712000 18000 1 AZST}
-    {3276460800 14400 0 AZT}
-    {3289161600 18000 1 AZST}
-    {3307910400 14400 0 AZT}
-    {3321216000 18000 1 AZST}
-    {3339360000 14400 0 AZT}
-    {3352665600 18000 1 AZST}
-    {3370809600 14400 0 AZT}
-    {3384115200 18000 1 AZST}
-    {3402864000 14400 0 AZT}
-    {3415564800 18000 1 AZST}
-    {3434313600 14400 0 AZT}
-    {3447014400 18000 1 AZST}
-    {3465763200 14400 0 AZT}
-    {3479068800 18000 1 AZST}
-    {3497212800 14400 0 AZT}
-    {3510518400 18000 1 AZST}
-    {3528662400 14400 0 AZT}
-    {3541968000 18000 1 AZST}
-    {3560112000 14400 0 AZT}
-    {3573417600 18000 1 AZST}
-    {3592166400 14400 0 AZT}
-    {3604867200 18000 1 AZST}
-    {3623616000 14400 0 AZT}
-    {3636316800 18000 1 AZST}
-    {3655065600 14400 0 AZT}
-    {3668371200 18000 1 AZST}
-    {3686515200 14400 0 AZT}
-    {3699820800 18000 1 AZST}
-    {3717964800 14400 0 AZT}
-    {3731270400 18000 1 AZST}
-    {3750019200 14400 0 AZT}
-    {3762720000 18000 1 AZST}
-    {3781468800 14400 0 AZT}
-    {3794169600 18000 1 AZST}
-    {3812918400 14400 0 AZT}
-    {3825619200 18000 1 AZST}
-    {3844368000 14400 0 AZT}
-    {3857673600 18000 1 AZST}
-    {3875817600 14400 0 AZT}
-    {3889123200 18000 1 AZST}
-    {3907267200 14400 0 AZT}
-    {3920572800 18000 1 AZST}
-    {3939321600 14400 0 AZT}
-    {3952022400 18000 1 AZST}
-    {3970771200 14400 0 AZT}
-    {3983472000 18000 1 AZST}
-    {4002220800 14400 0 AZT}
-    {4015526400 18000 1 AZST}
-    {4033670400 14400 0 AZT}
-    {4046976000 18000 1 AZST}
-    {4065120000 14400 0 AZT}
-    {4078425600 18000 1 AZST}
-    {4096569600 14400 0 AZT}
 }
diff --git a/library/tzdata/Asia/Barnaul b/library/tzdata/Asia/Barnaul
new file mode 100644 (file)
index 0000000..bf6abbf
--- /dev/null
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Barnaul) {
+    {-9223372036854775808 20100 0 LMT}
+    {-1579844100 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {748983600 25200 0 +07}
+    {764708400 28800 1 +08}
+    {780433200 25200 0 +07}
+    {796158000 28800 1 +08}
+    {801594000 25200 0 +07}
+    {811886400 21600 0 +06}
+    {828216000 25200 1 +07}
+    {846360000 21600 0 +06}
+    {859665600 25200 1 +07}
+    {877809600 21600 0 +06}
+    {891115200 25200 1 +07}
+    {909259200 21600 0 +06}
+    {922564800 25200 1 +07}
+    {941313600 21600 0 +06}
+    {954014400 25200 1 +07}
+    {972763200 21600 0 +06}
+    {985464000 25200 1 +07}
+    {1004212800 21600 0 +06}
+    {1017518400 25200 1 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
+    {1111867200 25200 1 +07}
+    {1130616000 21600 0 +06}
+    {1143316800 25200 1 +07}
+    {1162065600 21600 0 +06}
+    {1174766400 25200 1 +07}
+    {1193515200 21600 0 +06}
+    {1206820800 25200 1 +07}
+    {1224964800 21600 0 +06}
+    {1238270400 25200 1 +07}
+    {1256414400 21600 0 +06}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
+    {1414263600 21600 0 +06}
+    {1459022400 25200 0 +07}
+}
index 6aef523..2517beb 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Chita) {
     {670356000 32400 1 YAKST}
     {686080800 28800 0 YAKT}
     {695757600 32400 0 YAKMMTT}
-    {701791200 36000 1 YAKST}
-    {717512400 32400 0 YAKT}
+    {701802000 36000 1 YAKST}
+    {717526800 32400 0 YAKT}
     {733251600 36000 1 YAKST}
     {748976400 32400 0 YAKT}
     {764701200 36000 1 YAKST}
index 805b6b7..6adfe6d 100644 (file)
@@ -107,172 +107,172 @@ set TZData(:Asia/Gaza) {
     {1414098000 7200 0 EET}
     {1427493600 10800 1 EEST}
     {1445547600 7200 0 EET}
-    {1458943200 10800 1 EEST}
+    {1458946800 10800 1 EEST}
     {1476997200 7200 0 EET}
-    {1490997600 10800 1 EEST}
+    {1490396400 10800 1 EEST}
     {1509051600 7200 0 EET}
-    {1522447200 10800 1 EEST}
+    {1522450800 10800 1 EEST}
     {1540501200 7200 0 EET}
-    {1553896800 10800 1 EEST}
+    {1553900400 10800 1 EEST}
     {1571950800 7200 0 EET}
-    {1585346400 10800 1 EEST}
+    {1585350000 10800 1 EEST}
     {1603400400 7200 0 EET}
-    {1616796000 10800 1 EEST}
+    {1616799600 10800 1 EEST}
     {1634850000 7200 0 EET}
-    {1648245600 10800 1 EEST}
+    {1648249200 10800 1 EEST}
     {1666299600 7200 0 EET}
-    {1680300000 10800 1 EEST}
+    {1679698800 10800 1 EEST}
     {1698354000 7200 0 EET}
-    {1711749600 10800 1 EEST}
+    {1711753200 10800 1 EEST}
     {1729803600 7200 0 EET}
-    {1743199200 10800 1 EEST}
+    {1743202800 10800 1 EEST}
     {1761253200 7200 0 EET}
-    {1774648800 10800 1 EEST}
+    {1774652400 10800 1 EEST}
     {1792702800 7200 0 EET}
-    {1806098400 10800 1 EEST}
+    {1806102000 10800 1 EEST}
     {1824152400 7200 0 EET}
-    {1838152800 10800 1 EEST}
+    {1837551600 10800 1 EEST}
     {1856206800 7200 0 EET}
-    {1869602400 10800 1 EEST}
+    {1869606000 10800 1 EEST}
     {1887656400 7200 0 EET}
-    {1901052000 10800 1 EEST}
+    {1901055600 10800 1 EEST}
     {1919106000 7200 0 EET}
-    {1932501600 10800 1 EEST}
+    {1932505200 10800 1 EEST}
     {1950555600 7200 0 EET}
-    {1963951200 10800 1 EEST}
+    {1963954800 10800 1 EEST}
     {1982005200 7200 0 EET}
-    {1995400800 10800 1 EEST}
+    {1995404400 10800 1 EEST}
     {2013454800 7200 0 EET}
-    {2027455200 10800 1 EEST}
+    {2026854000 10800 1 EEST}
     {2045509200 7200 0 EET}
-    {2058904800 10800 1 EEST}
+    {2058908400 10800 1 EEST}
     {2076958800 7200 0 EET}
-    {2090354400 10800 1 EEST}
+    {2090358000 10800 1 EEST}
     {2108408400 7200 0 EET}
-    {2121804000 10800 1 EEST}
+    {2121807600 10800 1 EEST}
     {2139858000 7200 0 EET}
-    {2153253600 10800 1 EEST}
+    {2153257200 10800 1 EEST}
     {2171307600 7200 0 EET}
-    {2184703200 10800 1 EEST}
+    {2184706800 10800 1 EEST}
     {2202757200 7200 0 EET}
-    {2216757600 10800 1 EEST}
+    {2216761200 10800 1 EEST}
     {2234811600 7200 0 EET}
-    {2248207200 10800 1 EEST}
+    {2248210800 10800 1 EEST}
     {2266261200 7200 0 EET}
-    {2279656800 10800 1 EEST}
+    {2279660400 10800 1 EEST}
     {2297710800 7200 0 EET}
-    {2311106400 10800 1 EEST}
+    {2311110000 10800 1 EEST}
     {2329160400 7200 0 EET}
-    {2342556000 10800 1 EEST}
+    {2342559600 10800 1 EEST}
     {2360610000 7200 0 EET}
-    {2374610400 10800 1 EEST}
+    {2374009200 10800 1 EEST}
     {2392664400 7200 0 EET}
-    {2406060000 10800 1 EEST}
+    {2406063600 10800 1 EEST}
     {2424114000 7200 0 EET}
-    {2437509600 10800 1 EEST}
+    {2437513200 10800 1 EEST}
     {2455563600 7200 0 EET}
-    {2468959200 10800 1 EEST}
+    {2468962800 10800 1 EEST}
     {2487013200 7200 0 EET}
-    {2500408800 10800 1 EEST}
+    {2500412400 10800 1 EEST}
     {2518462800 7200 0 EET}
-    {2531858400 10800 1 EEST}
+    {2531862000 10800 1 EEST}
     {2549912400 7200 0 EET}
-    {2563912800 10800 1 EEST}
+    {2563311600 10800 1 EEST}
     {2581966800 7200 0 EET}
-    {2595362400 10800 1 EEST}
+    {2595366000 10800 1 EEST}
     {2613416400 7200 0 EET}
-    {2626812000 10800 1 EEST}
+    {2626815600 10800 1 EEST}
     {2644866000 7200 0 EET}
-    {2658261600 10800 1 EEST}
+    {2658265200 10800 1 EEST}
     {2676315600 7200 0 EET}
-    {2689711200 10800 1 EEST}
+    {2689714800 10800 1 EEST}
     {2707765200 7200 0 EET}
-    {2721765600 10800 1 EEST}
+    {2721164400 10800 1 EEST}
     {2739819600 7200 0 EET}
-    {2753215200 10800 1 EEST}
+    {2753218800 10800 1 EEST}
     {2771269200 7200 0 EET}
-    {2784664800 10800 1 EEST}
+    {2784668400 10800 1 EEST}
     {2802718800 7200 0 EET}
-    {2816114400 10800 1 EEST}
+    {2816118000 10800 1 EEST}
     {2834168400 7200 0 EET}
-    {2847564000 10800 1 EEST}
+    {2847567600 10800 1 EEST}
     {2865618000 7200 0 EET}
-    {2879013600 10800 1 EEST}
+    {2879017200 10800 1 EEST}
     {2897067600 7200 0 EET}
-    {2911068000 10800 1 EEST}
+    {2910466800 10800 1 EEST}
     {2929122000 7200 0 EET}
-    {2942517600 10800 1 EEST}
+    {2942521200 10800 1 EEST}
     {2960571600 7200 0 EET}
-    {2973967200 10800 1 EEST}
+    {2973970800 10800 1 EEST}
     {2992021200 7200 0 EET}
-    {3005416800 10800 1 EEST}
+    {3005420400 10800 1 EEST}
     {3023470800 7200 0 EET}
-    {3036866400 10800 1 EEST}
+    {3036870000 10800 1 EEST}
     {3054920400 7200 0 EET}
-    {3068316000 10800 1 EEST}
+    {3068319600 10800 1 EEST}
     {3086370000 7200 0 EET}
-    {3100370400 10800 1 EEST}
+    {3100374000 10800 1 EEST}
     {3118424400 7200 0 EET}
-    {3131820000 10800 1 EEST}
+    {3131823600 10800 1 EEST}
     {3149874000 7200 0 EET}
-    {3163269600 10800 1 EEST}
+    {3163273200 10800 1 EEST}
     {3181323600 7200 0 EET}
-    {3194719200 10800 1 EEST}
+    {3194722800 10800 1 EEST}
     {3212773200 7200 0 EET}
-    {3226168800 10800 1 EEST}
+    {3226172400 10800 1 EEST}
     {3244222800 7200 0 EET}
-    {3258223200 10800 1 EEST}
+    {3257622000 10800 1 EEST}
     {3276277200 7200 0 EET}
-    {3289672800 10800 1 EEST}
+    {3289676400 10800 1 EEST}
     {3307726800 7200 0 EET}
-    {3321122400 10800 1 EEST}
+    {3321126000 10800 1 EEST}
     {3339176400 7200 0 EET}
-    {3352572000 10800 1 EEST}
+    {3352575600 10800 1 EEST}
     {3370626000 7200 0 EET}
-    {3384021600 10800 1 EEST}
+    {3384025200 10800 1 EEST}
     {3402075600 7200 0 EET}
-    {3415471200 10800 1 EEST}
+    {3415474800 10800 1 EEST}
     {3433525200 7200 0 EET}
-    {3447525600 10800 1 EEST}
+    {3446924400 10800 1 EEST}
     {3465579600 7200 0 EET}
-    {3478975200 10800 1 EEST}
+    {3478978800 10800 1 EEST}
     {3497029200 7200 0 EET}
-    {3510424800 10800 1 EEST}
+    {3510428400 10800 1 EEST}
     {3528478800 7200 0 EET}
-    {3541874400 10800 1 EEST}
+    {3541878000 10800 1 EEST}
     {3559928400 7200 0 EET}
-    {3573324000 10800 1 EEST}
+    {3573327600 10800 1 EEST}
     {3591378000 7200 0 EET}
-    {3605378400 10800 1 EEST}
+    {3604777200 10800 1 EEST}
     {3623432400 7200 0 EET}
-    {3636828000 10800 1 EEST}
+    {3636831600 10800 1 EEST}
     {3654882000 7200 0 EET}
-    {3668277600 10800 1 EEST}
+    {3668281200 10800 1 EEST}
     {3686331600 7200 0 EET}
-    {3699727200 10800 1 EEST}
+    {3699730800 10800 1 EEST}
     {3717781200 7200 0 EET}
-    {3731176800 10800 1 EEST}
+    {3731180400 10800 1 EEST}
     {3749230800 7200 0 EET}
-    {3762626400 10800 1 EEST}
+    {3762630000 10800 1 EEST}
     {3780680400 7200 0 EET}
-    {3794680800 10800 1 EEST}
+    {3794079600 10800 1 EEST}
     {3812734800 7200 0 EET}
-    {3826130400 10800 1 EEST}
+    {3826134000 10800 1 EEST}
     {3844184400 7200 0 EET}
-    {3857580000 10800 1 EEST}
+    {3857583600 10800 1 EEST}
     {3875634000 7200 0 EET}
-    {3889029600 10800 1 EEST}
+    {3889033200 10800 1 EEST}
     {3907083600 7200 0 EET}
-    {3920479200 10800 1 EEST}
+    {3920482800 10800 1 EEST}
     {3938533200 7200 0 EET}
-    {3951928800 10800 1 EEST}
+    {3951932400 10800 1 EEST}
     {3969982800 7200 0 EET}
-    {3983983200 10800 1 EEST}
+    {3983986800 10800 1 EEST}
     {4002037200 7200 0 EET}
-    {4015432800 10800 1 EEST}
+    {4015436400 10800 1 EEST}
     {4033486800 7200 0 EET}
-    {4046882400 10800 1 EEST}
+    {4046886000 10800 1 EEST}
     {4064936400 7200 0 EET}
-    {4078332000 10800 1 EEST}
+    {4078335600 10800 1 EEST}
     {4096386000 7200 0 EET}
 }
index 9049d93..2db45f2 100644 (file)
@@ -106,172 +106,172 @@ set TZData(:Asia/Hebron) {
     {1414098000 7200 0 EET}
     {1427493600 10800 1 EEST}
     {1445547600 7200 0 EET}
-    {1458943200 10800 1 EEST}
+    {1458946800 10800 1 EEST}
     {1476997200 7200 0 EET}
-    {1490997600 10800 1 EEST}
+    {1490396400 10800 1 EEST}
     {1509051600 7200 0 EET}
-    {1522447200 10800 1 EEST}
+    {1522450800 10800 1 EEST}
     {1540501200 7200 0 EET}
-    {1553896800 10800 1 EEST}
+    {1553900400 10800 1 EEST}
     {1571950800 7200 0 EET}
-    {1585346400 10800 1 EEST}
+    {1585350000 10800 1 EEST}
     {1603400400 7200 0 EET}
-    {1616796000 10800 1 EEST}
+    {1616799600 10800 1 EEST}
     {1634850000 7200 0 EET}
-    {1648245600 10800 1 EEST}
+    {1648249200 10800 1 EEST}
     {1666299600 7200 0 EET}
-    {1680300000 10800 1 EEST}
+    {1679698800 10800 1 EEST}
     {1698354000 7200 0 EET}
-    {1711749600 10800 1 EEST}
+    {1711753200 10800 1 EEST}
     {1729803600 7200 0 EET}
-    {1743199200 10800 1 EEST}
+    {1743202800 10800 1 EEST}
     {1761253200 7200 0 EET}
-    {1774648800 10800 1 EEST}
+    {1774652400 10800 1 EEST}
     {1792702800 7200 0 EET}
-    {1806098400 10800 1 EEST}
+    {1806102000 10800 1 EEST}
     {1824152400 7200 0 EET}
-    {1838152800 10800 1 EEST}
+    {1837551600 10800 1 EEST}
     {1856206800 7200 0 EET}
-    {1869602400 10800 1 EEST}
+    {1869606000 10800 1 EEST}
     {1887656400 7200 0 EET}
-    {1901052000 10800 1 EEST}
+    {1901055600 10800 1 EEST}
     {1919106000 7200 0 EET}
-    {1932501600 10800 1 EEST}
+    {1932505200 10800 1 EEST}
     {1950555600 7200 0 EET}
-    {1963951200 10800 1 EEST}
+    {1963954800 10800 1 EEST}
     {1982005200 7200 0 EET}
-    {1995400800 10800 1 EEST}
+    {1995404400 10800 1 EEST}
     {2013454800 7200 0 EET}
-    {2027455200 10800 1 EEST}
+    {2026854000 10800 1 EEST}
     {2045509200 7200 0 EET}
-    {2058904800 10800 1 EEST}
+    {2058908400 10800 1 EEST}
     {2076958800 7200 0 EET}
-    {2090354400 10800 1 EEST}
+    {2090358000 10800 1 EEST}
     {2108408400 7200 0 EET}
-    {2121804000 10800 1 EEST}
+    {2121807600 10800 1 EEST}
     {2139858000 7200 0 EET}
-    {2153253600 10800 1 EEST}
+    {2153257200 10800 1 EEST}
     {2171307600 7200 0 EET}
-    {2184703200 10800 1 EEST}
+    {2184706800 10800 1 EEST}
     {2202757200 7200 0 EET}
-    {2216757600 10800 1 EEST}
+    {2216761200 10800 1 EEST}
     {2234811600 7200 0 EET}
-    {2248207200 10800 1 EEST}
+    {2248210800 10800 1 EEST}
     {2266261200 7200 0 EET}
-    {2279656800 10800 1 EEST}
+    {2279660400 10800 1 EEST}
     {2297710800 7200 0 EET}
-    {2311106400 10800 1 EEST}
+    {2311110000 10800 1 EEST}
     {2329160400 7200 0 EET}
-    {2342556000 10800 1 EEST}
+    {2342559600 10800 1 EEST}
     {2360610000 7200 0 EET}
-    {2374610400 10800 1 EEST}
+    {2374009200 10800 1 EEST}
     {2392664400 7200 0 EET}
-    {2406060000 10800 1 EEST}
+    {2406063600 10800 1 EEST}
     {2424114000 7200 0 EET}
-    {2437509600 10800 1 EEST}
+    {2437513200 10800 1 EEST}
     {2455563600 7200 0 EET}
-    {2468959200 10800 1 EEST}
+    {2468962800 10800 1 EEST}
     {2487013200 7200 0 EET}
-    {2500408800 10800 1 EEST}
+    {2500412400 10800 1 EEST}
     {2518462800 7200 0 EET}
-    {2531858400 10800 1 EEST}
+    {2531862000 10800 1 EEST}
     {2549912400 7200 0 EET}
-    {2563912800 10800 1 EEST}
+    {2563311600 10800 1 EEST}
     {2581966800 7200 0 EET}
-    {2595362400 10800 1 EEST}
+    {2595366000 10800 1 EEST}
     {2613416400 7200 0 EET}
-    {2626812000 10800 1 EEST}
+    {2626815600 10800 1 EEST}
     {2644866000 7200 0 EET}
-    {2658261600 10800 1 EEST}
+    {2658265200 10800 1 EEST}
     {2676315600 7200 0 EET}
-    {2689711200 10800 1 EEST}
+    {2689714800 10800 1 EEST}
     {2707765200 7200 0 EET}
-    {2721765600 10800 1 EEST}
+    {2721164400 10800 1 EEST}
     {2739819600 7200 0 EET}
-    {2753215200 10800 1 EEST}
+    {2753218800 10800 1 EEST}
     {2771269200 7200 0 EET}
-    {2784664800 10800 1 EEST}
+    {2784668400 10800 1 EEST}
     {2802718800 7200 0 EET}
-    {2816114400 10800 1 EEST}
+    {2816118000 10800 1 EEST}
     {2834168400 7200 0 EET}
-    {2847564000 10800 1 EEST}
+    {2847567600 10800 1 EEST}
     {2865618000 7200 0 EET}
-    {2879013600 10800 1 EEST}
+    {2879017200 10800 1 EEST}
     {2897067600 7200 0 EET}
-    {2911068000 10800 1 EEST}
+    {2910466800 10800 1 EEST}
     {2929122000 7200 0 EET}
-    {2942517600 10800 1 EEST}
+    {2942521200 10800 1 EEST}
     {2960571600 7200 0 EET}
-    {2973967200 10800 1 EEST}
+    {2973970800 10800 1 EEST}
     {2992021200 7200 0 EET}
-    {3005416800 10800 1 EEST}
+    {3005420400 10800 1 EEST}
     {3023470800 7200 0 EET}
-    {3036866400 10800 1 EEST}
+    {3036870000 10800 1 EEST}
     {3054920400 7200 0 EET}
-    {3068316000 10800 1 EEST}
+    {3068319600 10800 1 EEST}
     {3086370000 7200 0 EET}
-    {3100370400 10800 1 EEST}
+    {3100374000 10800 1 EEST}
     {3118424400 7200 0 EET}
-    {3131820000 10800 1 EEST}
+    {3131823600 10800 1 EEST}
     {3149874000 7200 0 EET}
-    {3163269600 10800 1 EEST}
+    {3163273200 10800 1 EEST}
     {3181323600 7200 0 EET}
-    {3194719200 10800 1 EEST}
+    {3194722800 10800 1 EEST}
     {3212773200 7200 0 EET}
-    {3226168800 10800 1 EEST}
+    {3226172400 10800 1 EEST}
     {3244222800 7200 0 EET}
-    {3258223200 10800 1 EEST}
+    {3257622000 10800 1 EEST}
     {3276277200 7200 0 EET}
-    {3289672800 10800 1 EEST}
+    {3289676400 10800 1 EEST}
     {3307726800 7200 0 EET}
-    {3321122400 10800 1 EEST}
+    {3321126000 10800 1 EEST}
     {3339176400 7200 0 EET}
-    {3352572000 10800 1 EEST}
+    {3352575600 10800 1 EEST}
     {3370626000 7200 0 EET}
-    {3384021600 10800 1 EEST}
+    {3384025200 10800 1 EEST}
     {3402075600 7200 0 EET}
-    {3415471200 10800 1 EEST}
+    {3415474800 10800 1 EEST}
     {3433525200 7200 0 EET}
-    {3447525600 10800 1 EEST}
+    {3446924400 10800 1 EEST}
     {3465579600 7200 0 EET}
-    {3478975200 10800 1 EEST}
+    {3478978800 10800 1 EEST}
     {3497029200 7200 0 EET}
-    {3510424800 10800 1 EEST}
+    {3510428400 10800 1 EEST}
     {3528478800 7200 0 EET}
-    {3541874400 10800 1 EEST}
+    {3541878000 10800 1 EEST}
     {3559928400 7200 0 EET}
-    {3573324000 10800 1 EEST}
+    {3573327600 10800 1 EEST}
     {3591378000 7200 0 EET}
-    {3605378400 10800 1 EEST}
+    {3604777200 10800 1 EEST}
     {3623432400 7200 0 EET}
-    {3636828000 10800 1 EEST}
+    {3636831600 10800 1 EEST}
     {3654882000 7200 0 EET}
-    {3668277600 10800 1 EEST}
+    {3668281200 10800 1 EEST}
     {3686331600 7200 0 EET}
-    {3699727200 10800 1 EEST}
+    {3699730800 10800 1 EEST}
     {3717781200 7200 0 EET}
-    {3731176800 10800 1 EEST}
+    {3731180400 10800 1 EEST}
     {3749230800 7200 0 EET}
-    {3762626400 10800 1 EEST}
+    {3762630000 10800 1 EEST}
     {3780680400 7200 0 EET}
-    {3794680800 10800 1 EEST}
+    {3794079600 10800 1 EEST}
     {3812734800 7200 0 EET}
-    {3826130400 10800 1 EEST}
+    {3826134000 10800 1 EEST}
     {3844184400 7200 0 EET}
-    {3857580000 10800 1 EEST}
+    {3857583600 10800 1 EEST}
     {3875634000 7200 0 EET}
-    {3889029600 10800 1 EEST}
+    {3889033200 10800 1 EEST}
     {3907083600 7200 0 EET}
-    {3920479200 10800 1 EEST}
+    {3920482800 10800 1 EEST}
     {3938533200 7200 0 EET}
-    {3951928800 10800 1 EEST}
+    {3951932400 10800 1 EEST}
     {3969982800 7200 0 EET}
-    {3983983200 10800 1 EEST}
+    {3983986800 10800 1 EEST}
     {4002037200 7200 0 EET}
-    {4015432800 10800 1 EEST}
+    {4015436400 10800 1 EEST}
     {4033486800 7200 0 EET}
-    {4046882400 10800 1 EEST}
+    {4046886000 10800 1 EEST}
     {4064936400 7200 0 EET}
-    {4078332000 10800 1 EEST}
+    {4078335600 10800 1 EEST}
     {4096386000 7200 0 EET}
 }
index 08e5798..ebe00c3 100644 (file)
@@ -29,8 +29,8 @@ set TZData(:Asia/Irkutsk) {
     {670359600 28800 1 IRKST}
     {686084400 25200 0 IRKT}
     {695761200 28800 0 IRKMMTT}
-    {701794800 32400 1 IRKST}
-    {717516000 28800 0 IRKT}
+    {701805600 32400 1 IRKST}
+    {717530400 28800 0 IRKT}
     {733255200 32400 1 IRKST}
     {748980000 28800 0 IRKT}
     {764704800 32400 1 IRKST}
index 82abcfa..2b77154 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Kamchatka) {
     {670345200 43200 1 PETST}
     {686070000 39600 0 PETT}
     {695746800 43200 0 PETMMTT}
-    {701780400 46800 1 PETST}
-    {717501600 43200 0 PETT}
+    {701791200 46800 1 PETST}
+    {717516000 43200 0 PETT}
     {733240800 46800 1 PETST}
     {748965600 43200 0 PETT}
     {764690400 46800 1 PETST}
index b2dc97a..b898e0d 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Khandyga) {
     {670356000 32400 1 YAKST}
     {686080800 28800 0 YAKT}
     {695757600 32400 0 YAKMMTT}
-    {701791200 36000 1 YAKST}
-    {717512400 32400 0 YAKT}
+    {701802000 36000 1 YAKST}
+    {717526800 32400 0 YAKT}
     {733251600 36000 1 YAKST}
     {748976400 32400 0 YAKT}
     {764701200 36000 1 YAKST}
index 17ea6c0..3c6285e 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Krasnoyarsk) {
     {670363200 25200 1 KRAST}
     {686088000 21600 0 KRAT}
     {695764800 25200 0 KRAMMTT}
-    {701798400 28800 1 KRAST}
-    {717519600 25200 0 KRAT}
+    {701809200 28800 1 KRAST}
+    {717534000 25200 0 KRAT}
     {733258800 28800 1 KRAST}
     {748983600 25200 0 KRAT}
     {764708400 28800 1 KRAST}
index bf796a7..afe78da 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Magadan) {
     {670348800 39600 1 MAGST}
     {686073600 36000 0 MAGT}
     {695750400 39600 0 MAGMMTT}
-    {701784000 43200 1 MAGST}
-    {717505200 39600 0 MAGT}
+    {701794800 43200 1 MAGST}
+    {717519600 39600 0 MAGT}
     {733244400 43200 1 MAGST}
     {748969200 39600 0 MAGT}
     {764694000 43200 1 MAGST}
@@ -68,4 +68,5 @@ set TZData(:Asia/Magadan) {
     {1288450800 39600 0 MAGT}
     {1301151600 43200 0 MAGT}
     {1414245600 36000 0 MAGT}
+    {1461427200 39600 0 MAGT}
 }
index ab3c2d5..a43a984 100644 (file)
@@ -2,71 +2,70 @@
 
 set TZData(:Asia/Novokuznetsk) {
     {-9223372036854775808 20928 0 LMT}
-    {-1441259328 21600 0 KRAT}
-    {-1247551200 25200 0 KRAMMTT}
-    {354906000 28800 1 KRAST}
-    {370713600 25200 0 KRAT}
-    {386442000 28800 1 KRAST}
-    {402249600 25200 0 KRAT}
-    {417978000 28800 1 KRAST}
-    {433785600 25200 0 KRAT}
-    {449600400 28800 1 KRAST}
-    {465332400 25200 0 KRAT}
-    {481057200 28800 1 KRAST}
-    {496782000 25200 0 KRAT}
-    {512506800 28800 1 KRAST}
-    {528231600 25200 0 KRAT}
-    {543956400 28800 1 KRAST}
-    {559681200 25200 0 KRAT}
-    {575406000 28800 1 KRAST}
-    {591130800 25200 0 KRAT}
-    {606855600 28800 1 KRAST}
-    {622580400 25200 0 KRAT}
-    {638305200 28800 1 KRAST}
-    {654634800 25200 0 KRAT}
-    {670359600 21600 0 KRAMMTT}
-    {670363200 25200 1 KRAST}
-    {686088000 21600 0 KRAT}
-    {695764800 25200 0 KRAMMTT}
-    {701798400 28800 1 KRAST}
-    {717519600 25200 0 KRAT}
-    {733258800 28800 1 KRAST}
-    {748983600 25200 0 KRAT}
-    {764708400 28800 1 KRAST}
-    {780433200 25200 0 KRAT}
-    {796158000 28800 1 KRAST}
-    {811882800 25200 0 KRAT}
-    {828212400 28800 1 KRAST}
-    {846356400 25200 0 KRAT}
-    {859662000 28800 1 KRAST}
-    {877806000 25200 0 KRAT}
-    {891111600 28800 1 KRAST}
-    {909255600 25200 0 KRAT}
-    {922561200 28800 1 KRAST}
-    {941310000 25200 0 KRAT}
-    {954010800 28800 1 KRAST}
-    {972759600 25200 0 KRAT}
-    {985460400 28800 1 KRAST}
-    {1004209200 25200 0 KRAT}
-    {1017514800 28800 1 KRAST}
-    {1035658800 25200 0 KRAT}
-    {1048964400 28800 1 KRAST}
-    {1067108400 25200 0 KRAT}
-    {1080414000 28800 1 KRAST}
-    {1099162800 25200 0 KRAT}
-    {1111863600 28800 1 KRAST}
-    {1130612400 25200 0 KRAT}
-    {1143313200 28800 1 KRAST}
-    {1162062000 25200 0 KRAT}
-    {1174762800 28800 1 KRAST}
-    {1193511600 25200 0 KRAT}
-    {1206817200 28800 1 KRAST}
-    {1224961200 25200 0 KRAT}
-    {1238266800 28800 1 KRAST}
-    {1256410800 25200 0 KRAT}
-    {1269716400 21600 0 NOVMMTT}
-    {1269720000 25200 1 NOVST}
-    {1288468800 21600 0 NOVT}
-    {1301169600 25200 0 NOVT}
-    {1414263600 25200 0 KRAT}
+    {-1441259328 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {748983600 25200 0 +07}
+    {764708400 28800 1 +08}
+    {780433200 25200 0 +07}
+    {796158000 28800 1 +08}
+    {811882800 25200 0 +07}
+    {828212400 28800 1 +08}
+    {846356400 25200 0 +07}
+    {859662000 28800 1 +08}
+    {877806000 25200 0 +07}
+    {891111600 28800 1 +08}
+    {909255600 25200 0 +07}
+    {922561200 28800 1 +08}
+    {941310000 25200 0 +07}
+    {954010800 28800 1 +08}
+    {972759600 25200 0 +07}
+    {985460400 28800 1 +08}
+    {1004209200 25200 0 +07}
+    {1017514800 28800 1 +08}
+    {1035658800 25200 0 +07}
+    {1048964400 28800 1 +08}
+    {1067108400 25200 0 +07}
+    {1080414000 28800 1 +08}
+    {1099162800 25200 0 +07}
+    {1111863600 28800 1 +08}
+    {1130612400 25200 0 +07}
+    {1143313200 28800 1 +08}
+    {1162062000 25200 0 +07}
+    {1174762800 28800 1 +08}
+    {1193511600 25200 0 +07}
+    {1206817200 28800 1 +08}
+    {1224961200 25200 0 +07}
+    {1238266800 28800 1 +08}
+    {1256410800 25200 0 +07}
+    {1269716400 21600 0 +07}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
 }
index 7227780..21f5c00 100644 (file)
@@ -2,71 +2,72 @@
 
 set TZData(:Asia/Novosibirsk) {
     {-9223372036854775808 19900 0 LMT}
-    {-1579476700 21600 0 NOVT}
-    {-1247551200 25200 0 NOVMMTT}
-    {354906000 28800 1 NOVST}
-    {370713600 25200 0 NOVT}
-    {386442000 28800 1 NOVST}
-    {402249600 25200 0 NOVT}
-    {417978000 28800 1 NOVST}
-    {433785600 25200 0 NOVT}
-    {449600400 28800 1 NOVST}
-    {465332400 25200 0 NOVT}
-    {481057200 28800 1 NOVST}
-    {496782000 25200 0 NOVT}
-    {512506800 28800 1 NOVST}
-    {528231600 25200 0 NOVT}
-    {543956400 28800 1 NOVST}
-    {559681200 25200 0 NOVT}
-    {575406000 28800 1 NOVST}
-    {591130800 25200 0 NOVT}
-    {606855600 28800 1 NOVST}
-    {622580400 25200 0 NOVT}
-    {638305200 28800 1 NOVST}
-    {654634800 25200 0 NOVT}
-    {670359600 21600 0 NOVMMTT}
-    {670363200 25200 1 NOVST}
-    {686088000 21600 0 NOVT}
-    {695764800 25200 0 NOVMMTT}
-    {701798400 28800 1 NOVST}
-    {717519600 25200 0 NOVT}
-    {733258800 28800 1 NOVST}
-    {738090000 25200 0 NOVST}
-    {748987200 21600 0 NOVT}
-    {764712000 25200 1 NOVST}
-    {780436800 21600 0 NOVT}
-    {796161600 25200 1 NOVST}
-    {811886400 21600 0 NOVT}
-    {828216000 25200 1 NOVST}
-    {846360000 21600 0 NOVT}
-    {859665600 25200 1 NOVST}
-    {877809600 21600 0 NOVT}
-    {891115200 25200 1 NOVST}
-    {909259200 21600 0 NOVT}
-    {922564800 25200 1 NOVST}
-    {941313600 21600 0 NOVT}
-    {954014400 25200 1 NOVST}
-    {972763200 21600 0 NOVT}
-    {985464000 25200 1 NOVST}
-    {1004212800 21600 0 NOVT}
-    {1017518400 25200 1 NOVST}
-    {1035662400 21600 0 NOVT}
-    {1048968000 25200 1 NOVST}
-    {1067112000 21600 0 NOVT}
-    {1080417600 25200 1 NOVST}
-    {1099166400 21600 0 NOVT}
-    {1111867200 25200 1 NOVST}
-    {1130616000 21600 0 NOVT}
-    {1143316800 25200 1 NOVST}
-    {1162065600 21600 0 NOVT}
-    {1174766400 25200 1 NOVST}
-    {1193515200 21600 0 NOVT}
-    {1206820800 25200 1 NOVST}
-    {1224964800 21600 0 NOVT}
-    {1238270400 25200 1 NOVST}
-    {1256414400 21600 0 NOVT}
-    {1269720000 25200 1 NOVST}
-    {1288468800 21600 0 NOVT}
-    {1301169600 25200 0 NOVT}
-    {1414263600 21600 0 NOVT}
+    {-1579476700 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {738090000 25200 0 +07}
+    {748987200 21600 0 +06}
+    {764712000 25200 1 +07}
+    {780436800 21600 0 +06}
+    {796161600 25200 1 +07}
+    {811886400 21600 0 +06}
+    {828216000 25200 1 +07}
+    {846360000 21600 0 +06}
+    {859665600 25200 1 +07}
+    {877809600 21600 0 +06}
+    {891115200 25200 1 +07}
+    {909259200 21600 0 +06}
+    {922564800 25200 1 +07}
+    {941313600 21600 0 +06}
+    {954014400 25200 1 +07}
+    {972763200 21600 0 +06}
+    {985464000 25200 1 +07}
+    {1004212800 21600 0 +06}
+    {1017518400 25200 1 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
+    {1111867200 25200 1 +07}
+    {1130616000 21600 0 +06}
+    {1143316800 25200 1 +07}
+    {1162065600 21600 0 +06}
+    {1174766400 25200 1 +07}
+    {1193515200 21600 0 +06}
+    {1206820800 25200 1 +07}
+    {1224964800 21600 0 +06}
+    {1238270400 25200 1 +07}
+    {1256414400 21600 0 +06}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
+    {1414263600 21600 0 +06}
+    {1469304000 25200 0 +07}
 }
index f25b8d4..a6fa180 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Omsk) {
     {670366800 21600 1 OMSST}
     {686091600 18000 0 OMST}
     {695768400 21600 0 OMSMMTT}
-    {701802000 25200 1 OMSST}
-    {717523200 21600 0 OMST}
+    {701812800 25200 1 OMSST}
+    {717537600 21600 0 OMST}
     {733262400 25200 1 OMSST}
     {748987200 21600 0 OMST}
     {764712000 25200 1 OMSST}
index 88b9a29..962111b 100644 (file)
@@ -2,57 +2,57 @@
 
 set TZData(:Asia/Oral) {
     {-9223372036854775808 12324 0 LMT}
-    {-1441164324 14400 0 URAT}
-    {-1247544000 18000 0 URAT}
-    {354913200 21600 1 URAST}
-    {370720800 21600 0 URAT}
-    {386445600 18000 0 URAT}
-    {386449200 21600 1 URAST}
-    {402256800 18000 0 URAT}
-    {417985200 21600 1 URAST}
-    {433792800 18000 0 URAT}
-    {449607600 21600 1 URAST}
-    {465339600 18000 0 URAT}
-    {481064400 21600 1 URAST}
-    {496789200 18000 0 URAT}
-    {512514000 21600 1 URAST}
-    {528238800 18000 0 URAT}
-    {543963600 21600 1 URAST}
-    {559688400 18000 0 URAT}
-    {575413200 21600 1 URAST}
-    {591138000 18000 0 URAT}
-    {606862800 14400 0 URAT}
-    {606866400 18000 1 URAST}
-    {622591200 14400 0 URAT}
-    {638316000 18000 1 URAST}
-    {654645600 14400 0 URAT}
-    {662673600 14400 0 URAT}
-    {692827200 14400 0 ORAT}
-    {701809200 18000 1 ORAST}
-    {717530400 14400 0 ORAT}
-    {733269600 18000 1 ORAST}
-    {748994400 14400 0 ORAT}
-    {764719200 18000 1 ORAST}
-    {780444000 14400 0 ORAT}
-    {796168800 18000 1 ORAST}
-    {811893600 14400 0 ORAT}
-    {828223200 18000 1 ORAST}
-    {846367200 14400 0 ORAT}
-    {859672800 18000 1 ORAST}
-    {877816800 14400 0 ORAT}
-    {891122400 18000 1 ORAST}
-    {909266400 14400 0 ORAT}
-    {922572000 18000 1 ORAST}
-    {941320800 14400 0 ORAT}
-    {954021600 18000 1 ORAST}
-    {972770400 14400 0 ORAT}
-    {985471200 18000 1 ORAST}
-    {1004220000 14400 0 ORAT}
-    {1017525600 18000 1 ORAST}
-    {1035669600 14400 0 ORAT}
-    {1048975200 18000 1 ORAST}
-    {1067119200 14400 0 ORAT}
-    {1080424800 18000 1 ORAST}
-    {1099173600 14400 0 ORAT}
-    {1110830400 18000 0 ORAT}
+    {-1441164324 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {354913200 21600 1 +06}
+    {370720800 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 14400 0 +04}
+    {606866400 18000 1 +05}
+    {622591200 14400 0 +04}
+    {638316000 18000 1 +05}
+    {654645600 14400 0 +04}
+    {670370400 18000 1 +05}
+    {686095200 14400 0 +04}
+    {701816400 14400 0 +04}
+    {701820000 18000 1 +05}
+    {717544800 14400 0 +04}
+    {733269600 18000 1 +05}
+    {748994400 14400 0 +04}
+    {764719200 18000 1 +05}
+    {780444000 14400 0 +04}
+    {796168800 18000 1 +05}
+    {811893600 14400 0 +04}
+    {828223200 18000 1 +05}
+    {846367200 14400 0 +04}
+    {859672800 18000 1 +05}
+    {877816800 14400 0 +04}
+    {891122400 18000 1 +05}
+    {909266400 14400 0 +04}
+    {922572000 18000 1 +05}
+    {941320800 14400 0 +04}
+    {954021600 18000 1 +05}
+    {972770400 14400 0 +04}
+    {985471200 18000 1 +05}
+    {1004220000 14400 0 +04}
+    {1017525600 18000 1 +05}
+    {1035669600 14400 0 +04}
+    {1048975200 18000 1 +05}
+    {1067119200 14400 0 +04}
+    {1080424800 18000 1 +05}
+    {1099173600 18000 0 +05}
 }
index 16da574..b2e9472 100644 (file)
@@ -2,57 +2,56 @@
 
 set TZData(:Asia/Qyzylorda) {
     {-9223372036854775808 15712 0 LMT}
-    {-1441167712 14400 0 KIZT}
-    {-1247544000 18000 0 KIZT}
-    {354913200 21600 1 KIZST}
-    {370720800 21600 0 KIZT}
-    {386445600 18000 0 KIZT}
-    {386449200 21600 1 KIZST}
-    {402256800 18000 0 KIZT}
-    {417985200 21600 1 KIZST}
-    {433792800 18000 0 KIZT}
-    {449607600 21600 1 KIZST}
-    {465339600 18000 0 KIZT}
-    {481064400 21600 1 KIZST}
-    {496789200 18000 0 KIZT}
-    {512514000 21600 1 KIZST}
-    {528238800 18000 0 KIZT}
-    {543963600 21600 1 KIZST}
-    {559688400 18000 0 KIZT}
-    {575413200 21600 1 KIZST}
-    {591138000 18000 0 KIZT}
-    {606862800 21600 1 KIZST}
-    {622587600 18000 0 KIZT}
-    {638312400 21600 1 KIZST}
-    {654642000 18000 0 KIZT}
-    {662670000 18000 0 KIZT}
-    {692823600 18000 0 QYZT}
-    {695768400 21600 0 QYZT}
-    {701802000 25200 1 QYZST}
-    {717523200 21600 0 QYZT}
-    {733262400 25200 1 QYZST}
-    {748987200 21600 0 QYZT}
-    {764712000 25200 1 QYZST}
-    {780436800 21600 0 QYZT}
-    {796161600 25200 1 QYZST}
-    {811886400 21600 0 QYZT}
-    {828216000 25200 1 QYZST}
-    {846360000 21600 0 QYZT}
-    {859665600 25200 1 QYZST}
-    {877809600 21600 0 QYZT}
-    {891115200 25200 1 QYZST}
-    {909259200 21600 0 QYZT}
-    {922564800 25200 1 QYZST}
-    {941313600 21600 0 QYZT}
-    {954014400 25200 1 QYZST}
-    {972763200 21600 0 QYZT}
-    {985464000 25200 1 QYZST}
-    {1004212800 21600 0 QYZT}
-    {1017518400 25200 1 QYZST}
-    {1035662400 21600 0 QYZT}
-    {1048968000 25200 1 QYZST}
-    {1067112000 21600 0 QYZT}
-    {1080417600 25200 1 QYZST}
-    {1099166400 21600 0 QYZT}
-    {1110823200 21600 0 QYZT}
+    {-1441167712 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {354913200 21600 1 +06}
+    {370720800 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 21600 1 +06}
+    {622587600 18000 0 +05}
+    {638312400 21600 1 +06}
+    {654642000 18000 0 +05}
+    {670366800 14400 0 +04}
+    {670370400 18000 1 +05}
+    {701812800 18000 0 +05}
+    {701816400 21600 1 +06}
+    {717541200 18000 0 +05}
+    {733266000 21600 1 +06}
+    {748990800 18000 0 +05}
+    {764715600 21600 1 +06}
+    {780440400 18000 0 +05}
+    {796165200 21600 1 +06}
+    {811890000 18000 0 +05}
+    {828219600 21600 1 +06}
+    {846363600 18000 0 +05}
+    {859669200 21600 1 +06}
+    {877813200 18000 0 +05}
+    {891118800 21600 1 +06}
+    {909262800 18000 0 +05}
+    {922568400 21600 1 +06}
+    {941317200 18000 0 +05}
+    {954018000 21600 1 +06}
+    {972766800 18000 0 +05}
+    {985467600 21600 1 +06}
+    {1004216400 18000 0 +05}
+    {1017522000 21600 1 +06}
+    {1035666000 18000 0 +05}
+    {1048971600 21600 1 +06}
+    {1067115600 18000 0 +05}
+    {1080421200 21600 1 +06}
+    {1099170000 21600 0 +06}
 }
index eed20ba..1de22f4 100644 (file)
@@ -29,8 +29,8 @@ set TZData(:Asia/Sakhalin) {
     {670348800 39600 1 SAKST}
     {686073600 36000 0 SAKT}
     {695750400 39600 0 SAKMMTT}
-    {701784000 43200 1 SAKST}
-    {717505200 39600 0 SAKT}
+    {701794800 43200 1 SAKST}
+    {717519600 39600 0 SAKT}
     {733244400 43200 1 SAKST}
     {748969200 39600 0 SAKT}
     {764694000 43200 1 SAKST}
@@ -70,4 +70,5 @@ set TZData(:Asia/Sakhalin) {
     {1288454400 36000 0 SAKT}
     {1301155200 39600 0 SAKT}
     {1414249200 36000 0 SAKT}
+    {1459008000 39600 0 SAKT}
 }
index d1dd879..a0586aa 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Srednekolymsk) {
     {670348800 39600 1 MAGST}
     {686073600 36000 0 MAGT}
     {695750400 39600 0 MAGMMTT}
-    {701784000 43200 1 MAGST}
-    {717505200 39600 0 MAGT}
+    {701794800 43200 1 MAGST}
+    {717519600 39600 0 MAGT}
     {733244400 43200 1 MAGST}
     {748969200 39600 0 MAGT}
     {764694000 43200 1 MAGST}
diff --git a/library/tzdata/Asia/Tomsk b/library/tzdata/Asia/Tomsk
new file mode 100644 (file)
index 0000000..0694d01
--- /dev/null
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Tomsk) {
+    {-9223372036854775808 20391 0 LMT}
+    {-1578807591 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {748983600 25200 0 +07}
+    {764708400 28800 1 +08}
+    {780433200 25200 0 +07}
+    {796158000 28800 1 +08}
+    {811882800 25200 0 +07}
+    {828212400 28800 1 +08}
+    {846356400 25200 0 +07}
+    {859662000 28800 1 +08}
+    {877806000 25200 0 +07}
+    {891111600 28800 1 +08}
+    {909255600 25200 0 +07}
+    {922561200 28800 1 +08}
+    {941310000 25200 0 +07}
+    {954010800 28800 1 +08}
+    {972759600 25200 0 +07}
+    {985460400 28800 1 +08}
+    {1004209200 25200 0 +07}
+    {1017514800 28800 1 +08}
+    {1020196800 25200 0 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
+    {1111867200 25200 1 +07}
+    {1130616000 21600 0 +06}
+    {1143316800 25200 1 +07}
+    {1162065600 21600 0 +06}
+    {1174766400 25200 1 +07}
+    {1193515200 21600 0 +06}
+    {1206820800 25200 1 +07}
+    {1224964800 21600 0 +06}
+    {1238270400 25200 1 +07}
+    {1256414400 21600 0 +06}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
+    {1414263600 21600 0 +06}
+    {1464465600 25200 0 +07}
+}
index 90fa7d5..3380b7b 100644 (file)
@@ -27,8 +27,8 @@ set TZData(:Asia/Ust-Nera) {
     {670348800 39600 1 MAGST}
     {686073600 36000 0 MAGT}
     {695750400 39600 0 MAGMMTT}
-    {701784000 43200 1 MAGST}
-    {717505200 39600 0 MAGT}
+    {701794800 43200 1 MAGST}
+    {717519600 39600 0 MAGT}
     {733244400 43200 1 MAGST}
     {748969200 39600 0 MAGT}
     {764694000 43200 1 MAGST}
index 119ff57..b279d1c 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Vladivostok) {
     {670352400 36000 1 VLAST}
     {686077200 32400 0 VLAT}
     {695754000 36000 0 VLAMMTT}
-    {701787600 39600 1 VLAST}
-    {717508800 36000 0 VLAT}
+    {701798400 39600 1 VLAST}
+    {717523200 36000 0 VLAT}
     {733248000 39600 1 VLAST}
     {748972800 36000 0 VLAT}
     {764697600 39600 1 VLAST}
index 17493a6..0074379 100644 (file)
@@ -28,8 +28,8 @@ set TZData(:Asia/Yakutsk) {
     {670356000 32400 1 YAKST}
     {686080800 28800 0 YAKT}
     {695757600 32400 0 YAKMMTT}
-    {701791200 36000 1 YAKST}
-    {717512400 32400 0 YAKT}
+    {701802000 36000 1 YAKST}
+    {717526800 32400 0 YAKT}
     {733251600 36000 1 YAKST}
     {748976400 32400 0 YAKT}
     {764701200 36000 1 YAKST}
index 2678958..fdd89b0 100644 (file)
@@ -29,8 +29,8 @@ set TZData(:Asia/Yekaterinburg) {
     {670370400 18000 1 SVEST}
     {686095200 14400 0 SVET}
     {695772000 18000 0 YEKMMTT}
-    {701805600 21600 1 YEKST}
-    {717526800 18000 0 YEKT}
+    {701816400 21600 1 YEKST}
+    {717541200 18000 0 YEKT}
     {733266000 21600 1 YEKST}
     {748990800 18000 0 YEKT}
     {764715600 21600 1 YEKST}
index 22008ef..c552403 100644 (file)
@@ -27,8 +27,8 @@ set TZData(:Asia/Yerevan) {
     {670370400 14400 1 YERST}
     {685569600 14400 0 AMST}
     {686098800 10800 0 AMT}
-    {701812800 14400 1 AMST}
-    {717534000 10800 0 AMT}
+    {701823600 14400 1 AMST}
+    {717548400 10800 0 AMT}
     {733273200 14400 1 AMST}
     {748998000 10800 0 AMT}
     {764722800 14400 1 AMST}
@@ -66,5 +66,5 @@ set TZData(:Asia/Yerevan) {
     {1288476000 14400 0 AMT}
     {1301176800 18000 1 AMST}
     {1319925600 14400 0 AMT}
-    {1332626400 14400 0 AMT}
+    {1328731200 14400 0 AMT}
 }
diff --git a/library/tzdata/Europe/Astrakhan b/library/tzdata/Europe/Astrakhan
new file mode 100644 (file)
index 0000000..9881bb8
--- /dev/null
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Astrakhan) {
+    {-9223372036854775808 11532 0 LMT}
+    {-1441249932 10800 0 +03}
+    {-1247540400 14400 0 +05}
+    {354916800 18000 1 +05}
+    {370724400 14400 0 +04}
+    {386452800 18000 1 +05}
+    {402260400 14400 0 +04}
+    {417988800 18000 1 +05}
+    {433796400 14400 0 +04}
+    {449611200 18000 1 +05}
+    {465343200 14400 0 +04}
+    {481068000 18000 1 +05}
+    {496792800 14400 0 +04}
+    {512517600 18000 1 +05}
+    {528242400 14400 0 +04}
+    {543967200 18000 1 +05}
+    {559692000 14400 0 +04}
+    {575416800 18000 1 +05}
+    {591141600 14400 0 +04}
+    {606866400 10800 0 +04}
+    {606870000 14400 1 +04}
+    {622594800 10800 0 +03}
+    {638319600 14400 1 +04}
+    {654649200 10800 0 +03}
+    {670374000 14400 0 +04}
+    {701820000 10800 0 +04}
+    {701823600 14400 1 +04}
+    {717548400 10800 0 +03}
+    {733273200 14400 1 +04}
+    {748998000 10800 0 +03}
+    {764722800 14400 1 +04}
+    {780447600 10800 0 +03}
+    {796172400 14400 1 +04}
+    {811897200 10800 0 +03}
+    {828226800 14400 1 +04}
+    {846370800 10800 0 +03}
+    {859676400 14400 1 +04}
+    {877820400 10800 0 +03}
+    {891126000 14400 1 +04}
+    {909270000 10800 0 +03}
+    {922575600 14400 1 +04}
+    {941324400 10800 0 +03}
+    {954025200 14400 1 +04}
+    {972774000 10800 0 +03}
+    {985474800 14400 1 +04}
+    {1004223600 10800 0 +03}
+    {1017529200 14400 1 +04}
+    {1035673200 10800 0 +03}
+    {1048978800 14400 1 +04}
+    {1067122800 10800 0 +03}
+    {1080428400 14400 1 +04}
+    {1099177200 10800 0 +03}
+    {1111878000 14400 1 +04}
+    {1130626800 10800 0 +03}
+    {1143327600 14400 1 +04}
+    {1162076400 10800 0 +03}
+    {1174777200 14400 1 +04}
+    {1193526000 10800 0 +03}
+    {1206831600 14400 1 +04}
+    {1224975600 10800 0 +03}
+    {1238281200 14400 1 +04}
+    {1256425200 10800 0 +03}
+    {1269730800 14400 1 +04}
+    {1288479600 10800 0 +03}
+    {1301180400 14400 0 +04}
+    {1414274400 10800 0 +03}
+    {1459033200 14400 0 +04}
+}
index 5c240e7..db4c6db 100644 (file)
@@ -46,9 +46,9 @@ set TZData(:Europe/Chisinau) {
     {591145200 10800 0 MSK}
     {606870000 14400 1 MSD}
     {622594800 10800 0 MSK}
-    {631141200 10800 0 MSK}
-    {641941200 7200 0 EET}
-    {662680800 7200 0 EEMMTT}
+    {638319600 14400 1 MSD}
+    {641948400 10800 0 EEST}
+    {654652800 7200 0 EET}
     {670377600 10800 1 EEST}
     {686102400 7200 0 EET}
     {694216800 7200 0 EET}
index d03f7d0..85add82 100644 (file)
@@ -35,15 +35,15 @@ set TZData(:Europe/Kaliningrad) {
     {559695600 10800 0 MSK}
     {575420400 14400 1 MSD}
     {591145200 10800 0 MSK}
-    {606870000 14400 1 MSD}
-    {622594800 10800 0 MSK}
-    {638319600 14400 1 MSD}
-    {654649200 10800 0 MSK}
-    {670374000 7200 0 EEMMTT}
+    {606870000 7200 0 EEMMTT}
+    {606873600 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
     {670377600 10800 1 EEST}
     {686102400 7200 0 EET}
-    {701816400 10800 1 EEST}
-    {717537600 7200 0 EET}
+    {701827200 10800 1 EEST}
+    {717552000 7200 0 EET}
     {733276800 10800 1 EEST}
     {749001600 7200 0 EET}
     {764726400 10800 1 EEST}
diff --git a/library/tzdata/Europe/Kirov b/library/tzdata/Europe/Kirov
new file mode 100644 (file)
index 0000000..82ffc9e
--- /dev/null
@@ -0,0 +1,70 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Kirov) {
+    {-9223372036854775808 11928 0 LMT}
+    {-1593825528 10800 0 +03}
+    {-1247540400 14400 0 +05}
+    {354916800 18000 1 +05}
+    {370724400 14400 0 +04}
+    {386452800 18000 1 +05}
+    {402260400 14400 0 +04}
+    {417988800 18000 1 +05}
+    {433796400 14400 0 +04}
+    {449611200 18000 1 +05}
+    {465343200 14400 0 +04}
+    {481068000 18000 1 +05}
+    {496792800 14400 0 +04}
+    {512517600 18000 1 +05}
+    {528242400 14400 0 +04}
+    {543967200 18000 1 +05}
+    {559692000 14400 0 +04}
+    {575416800 18000 1 +05}
+    {591141600 14400 0 +04}
+    {606866400 10800 0 +04}
+    {606870000 14400 1 +04}
+    {622594800 10800 0 +03}
+    {638319600 14400 1 +04}
+    {654649200 10800 0 +03}
+    {670374000 14400 0 +04}
+    {701820000 10800 0 +04}
+    {701823600 14400 1 +04}
+    {717548400 10800 0 +03}
+    {733273200 14400 1 +04}
+    {748998000 10800 0 +03}
+    {764722800 14400 1 +04}
+    {780447600 10800 0 +03}
+    {796172400 14400 1 +04}
+    {811897200 10800 0 +03}
+    {828226800 14400 1 +04}
+    {846370800 10800 0 +03}
+    {859676400 14400 1 +04}
+    {877820400 10800 0 +03}
+    {891126000 14400 1 +04}
+    {909270000 10800 0 +03}
+    {922575600 14400 1 +04}
+    {941324400 10800 0 +03}
+    {954025200 14400 1 +04}
+    {972774000 10800 0 +03}
+    {985474800 14400 1 +04}
+    {1004223600 10800 0 +03}
+    {1017529200 14400 1 +04}
+    {1035673200 10800 0 +03}
+    {1048978800 14400 1 +04}
+    {1067122800 10800 0 +03}
+    {1080428400 14400 1 +04}
+    {1099177200 10800 0 +03}
+    {1111878000 14400 1 +04}
+    {1130626800 10800 0 +03}
+    {1143327600 14400 1 +04}
+    {1162076400 10800 0 +03}
+    {1174777200 14400 1 +04}
+    {1193526000 10800 0 +03}
+    {1206831600 14400 1 +04}
+    {1224975600 10800 0 +03}
+    {1238281200 14400 1 +04}
+    {1256425200 10800 0 +03}
+    {1269730800 14400 1 +04}
+    {1288479600 10800 0 +03}
+    {1301180400 14400 0 +04}
+    {1414274400 10800 0 +03}
+}
index 0acb4aa..2857e5b 100644 (file)
@@ -30,10 +30,11 @@ set TZData(:Europe/Minsk) {
     {606870000 14400 1 MSD}
     {622594800 10800 0 MSK}
     {631141200 10800 0 MSK}
-    {670374000 10800 1 EEST}
+    {670374000 7200 0 EEMMTT}
+    {670377600 10800 1 EEST}
     {686102400 7200 0 EET}
-    {701820000 10800 1 EEST}
-    {717544800 7200 0 EET}
+    {701827200 10800 1 EEST}
+    {717552000 7200 0 EET}
     {733276800 10800 1 EEST}
     {749001600 7200 0 EET}
     {764726400 10800 1 EEST}
index 686b3d0..1e2f45b 100644 (file)
@@ -40,8 +40,8 @@ set TZData(:Europe/Moscow) {
     {670377600 10800 1 EEST}
     {686102400 7200 0 EET}
     {695779200 10800 0 MSD}
-    {701812800 14400 1 MSD}
-    {717534000 10800 0 MSK}
+    {701823600 14400 1 MSD}
+    {717548400 10800 0 MSK}
     {733273200 14400 1 MSD}
     {748998000 10800 0 MSK}
     {764722800 14400 1 MSD}
index ee9d989..08203c0 100644 (file)
@@ -28,10 +28,10 @@ set TZData(:Europe/Samara) {
     {654649200 10800 0 MSK}
     {670374000 7200 0 EEMMTT}
     {670377600 10800 1 EEST}
-    {686102400 10800 0 KUYT}
+    {686102400 10800 0 SAMT}
     {687916800 14400 0 SAMT}
-    {701809200 18000 1 SAMST}
-    {717530400 14400 0 SAMT}
+    {701820000 18000 1 SAMST}
+    {717544800 14400 0 SAMT}
     {733269600 18000 1 SAMST}
     {748994400 14400 0 SAMT}
     {764719200 18000 1 SAMST}
diff --git a/library/tzdata/Europe/Ulyanovsk b/library/tzdata/Europe/Ulyanovsk
new file mode 100644 (file)
index 0000000..d5c33b5
--- /dev/null
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Ulyanovsk) {
+    {-9223372036854775808 11616 0 LMT}
+    {-1593825216 10800 0 +03}
+    {-1247540400 14400 0 +05}
+    {354916800 18000 1 +05}
+    {370724400 14400 0 +04}
+    {386452800 18000 1 +05}
+    {402260400 14400 0 +04}
+    {417988800 18000 1 +05}
+    {433796400 14400 0 +04}
+    {449611200 18000 1 +05}
+    {465343200 14400 0 +04}
+    {481068000 18000 1 +05}
+    {496792800 14400 0 +04}
+    {512517600 18000 1 +05}
+    {528242400 14400 0 +04}
+    {543967200 18000 1 +05}
+    {559692000 14400 0 +04}
+    {575416800 18000 1 +05}
+    {591141600 14400 0 +04}
+    {606866400 10800 0 +04}
+    {606870000 14400 1 +04}
+    {622594800 10800 0 +03}
+    {638319600 14400 1 +04}
+    {654649200 10800 0 +03}
+    {670374000 7200 0 +03}
+    {670377600 10800 1 +03}
+    {686102400 7200 0 +02}
+    {695779200 10800 0 +04}
+    {701823600 14400 1 +04}
+    {717548400 10800 0 +03}
+    {733273200 14400 1 +04}
+    {748998000 10800 0 +03}
+    {764722800 14400 1 +04}
+    {780447600 10800 0 +03}
+    {796172400 14400 1 +04}
+    {811897200 10800 0 +03}
+    {828226800 14400 1 +04}
+    {846370800 10800 0 +03}
+    {859676400 14400 1 +04}
+    {877820400 10800 0 +03}
+    {891126000 14400 1 +04}
+    {909270000 10800 0 +03}
+    {922575600 14400 1 +04}
+    {941324400 10800 0 +03}
+    {954025200 14400 1 +04}
+    {972774000 10800 0 +03}
+    {985474800 14400 1 +04}
+    {1004223600 10800 0 +03}
+    {1017529200 14400 1 +04}
+    {1035673200 10800 0 +03}
+    {1048978800 14400 1 +04}
+    {1067122800 10800 0 +03}
+    {1080428400 14400 1 +04}
+    {1099177200 10800 0 +03}
+    {1111878000 14400 1 +04}
+    {1130626800 10800 0 +03}
+    {1143327600 14400 1 +04}
+    {1162076400 10800 0 +03}
+    {1174777200 14400 1 +04}
+    {1193526000 10800 0 +03}
+    {1206831600 14400 1 +04}
+    {1224975600 10800 0 +03}
+    {1238281200 14400 1 +04}
+    {1256425200 10800 0 +03}
+    {1269730800 14400 1 +04}
+    {1288479600 10800 0 +03}
+    {1301180400 14400 0 +04}
+    {1414274400 10800 0 +03}
+    {1459033200 14400 0 +04}
+}
index 62d5d87..5e73150 100644 (file)
@@ -30,11 +30,12 @@ set TZData(:Europe/Vilnius) {
     {559695600 10800 0 MSK}
     {575420400 14400 1 MSD}
     {591145200 10800 0 MSK}
-    {606870000 14400 1 MSD}
-    {622594800 10800 0 MSK}
-    {638319600 14400 1 MSD}
-    {654649200 10800 0 MSK}
-    {670374000 10800 1 EEST}
+    {606870000 7200 0 EEMMTT}
+    {606873600 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {670377600 10800 1 EEST}
     {686102400 7200 0 EET}
     {701827200 10800 1 EEST}
     {717552000 7200 0 EET}
index d71fb0b..83996b0 100644 (file)
@@ -20,16 +20,17 @@ set TZData(:Europe/Volgograd) {
     {528242400 14400 0 VOLT}
     {543967200 18000 1 VOLST}
     {559692000 14400 0 VOLT}
-    {575416800 18000 1 VOLST}
-    {591141600 14400 0 VOLT}
-    {606866400 10800 0 VOLMMTT}
+    {575416800 10800 0 VOLMMTT}
+    {575420400 14400 1 VOLST}
+    {591145200 10800 0 VOLT}
     {606870000 14400 1 VOLST}
     {622594800 10800 0 VOLT}
     {638319600 14400 1 VOLST}
     {654649200 10800 0 VOLT}
     {670374000 14400 0 VOLT}
-    {701820000 14400 0 MSD}
-    {717534000 10800 0 MSK}
+    {701820000 10800 0 MSD}
+    {701823600 14400 1 MSD}
+    {717548400 10800 0 MSK}
     {733273200 14400 1 MSD}
     {748998000 10800 0 MSK}
     {764722800 14400 1 MSD}
index b41b85a..8820010 100644 (file)
@@ -1,6 +1,6 @@
 # created by tools/tclZIC.tcl - do not edit
 
 set TZData(:Indian/Kerguelen) {
-    {-9223372036854775808 0 0 zzz}
+    {-9223372036854775808 0 0 -00}
     {-631152000 18000 0 TFT}
 }
index 4b45ba2..ef0f2d5 100644 (file)
@@ -97,5 +97,172 @@ set TZData(:Pacific/Easter) {
     {1378612800 -18000 1 EASST}
     {1398567600 -21600 0 EAST}
     {1410062400 -18000 1 EASST}
-    {1430017200 -18000 0 EAST}
+    {1463281200 -21600 0 EAST}
+    {1471147200 -18000 1 EASST}
+    {1494730800 -21600 0 EAST}
+    {1502596800 -18000 1 EASST}
+    {1526180400 -21600 0 EAST}
+    {1534046400 -18000 1 EASST}
+    {1557630000 -21600 0 EAST}
+    {1565496000 -18000 1 EASST}
+    {1589079600 -21600 0 EAST}
+    {1596945600 -18000 1 EASST}
+    {1620529200 -21600 0 EAST}
+    {1629000000 -18000 1 EASST}
+    {1652583600 -21600 0 EAST}
+    {1660449600 -18000 1 EASST}
+    {1684033200 -21600 0 EAST}
+    {1691899200 -18000 1 EASST}
+    {1715482800 -21600 0 EAST}
+    {1723348800 -18000 1 EASST}
+    {1746932400 -21600 0 EAST}
+    {1754798400 -18000 1 EASST}
+    {1778382000 -21600 0 EAST}
+    {1786248000 -18000 1 EASST}
+    {1809831600 -21600 0 EAST}
+    {1818302400 -18000 1 EASST}
+    {1841886000 -21600 0 EAST}
+    {1849752000 -18000 1 EASST}
+    {1873335600 -21600 0 EAST}
+    {1881201600 -18000 1 EASST}
+    {1904785200 -21600 0 EAST}
+    {1912651200 -18000 1 EASST}
+    {1936234800 -21600 0 EAST}
+    {1944100800 -18000 1 EASST}
+    {1967684400 -21600 0 EAST}
+    {1976155200 -18000 1 EASST}
+    {1999738800 -21600 0 EAST}
+    {2007604800 -18000 1 EASST}
+    {2031188400 -21600 0 EAST}
+    {2039054400 -18000 1 EASST}
+    {2062638000 -21600 0 EAST}
+    {2070504000 -18000 1 EASST}
+    {2094087600 -21600 0 EAST}
+    {2101953600 -18000 1 EASST}
+    {2125537200 -21600 0 EAST}
+    {2133403200 -18000 1 EASST}
+    {2156986800 -21600 0 EAST}
+    {2165457600 -18000 1 EASST}
+    {2189041200 -21600 0 EAST}
+    {2196907200 -18000 1 EASST}
+    {2220490800 -21600 0 EAST}
+    {2228356800 -18000 1 EASST}
+    {2251940400 -21600 0 EAST}
+    {2259806400 -18000 1 EASST}
+    {2283390000 -21600 0 EAST}
+    {2291256000 -18000 1 EASST}
+    {2314839600 -21600 0 EAST}
+    {2322705600 -18000 1 EASST}
+    {2346894000 -21600 0 EAST}
+    {2354760000 -18000 1 EASST}
+    {2378343600 -21600 0 EAST}
+    {2386209600 -18000 1 EASST}
+    {2409793200 -21600 0 EAST}
+    {2417659200 -18000 1 EASST}
+    {2441242800 -21600 0 EAST}
+    {2449108800 -18000 1 EASST}
+    {2472692400 -21600 0 EAST}
+    {2480558400 -18000 1 EASST}
+    {2504142000 -21600 0 EAST}
+    {2512612800 -18000 1 EASST}
+    {2536196400 -21600 0 EAST}
+    {2544062400 -18000 1 EASST}
+    {2567646000 -21600 0 EAST}
+    {2575512000 -18000 1 EASST}
+    {2599095600 -21600 0 EAST}
+    {2606961600 -18000 1 EASST}
+    {2630545200 -21600 0 EAST}
+    {2638411200 -18000 1 EASST}
+    {2661994800 -21600 0 EAST}
+    {2669860800 -18000 1 EASST}
+    {2693444400 -21600 0 EAST}
+    {2701915200 -18000 1 EASST}
+    {2725498800 -21600 0 EAST}
+    {2733364800 -18000 1 EASST}
+    {2756948400 -21600 0 EAST}
+    {2764814400 -18000 1 EASST}
+    {2788398000 -21600 0 EAST}
+    {2796264000 -18000 1 EASST}
+    {2819847600 -21600 0 EAST}
+    {2827713600 -18000 1 EASST}
+    {2851297200 -21600 0 EAST}
+    {2859768000 -18000 1 EASST}
+    {2883351600 -21600 0 EAST}
+    {2891217600 -18000 1 EASST}
+    {2914801200 -21600 0 EAST}
+    {2922667200 -18000 1 EASST}
+    {2946250800 -21600 0 EAST}
+    {2954116800 -18000 1 EASST}
+    {2977700400 -21600 0 EAST}
+    {2985566400 -18000 1 EASST}
+    {3009150000 -21600 0 EAST}
+    {3017016000 -18000 1 EASST}
+    {3040599600 -21600 0 EAST}
+    {3049070400 -18000 1 EASST}
+    {3072654000 -21600 0 EAST}
+    {3080520000 -18000 1 EASST}
+    {3104103600 -21600 0 EAST}
+    {3111969600 -18000 1 EASST}
+    {3135553200 -21600 0 EAST}
+    {3143419200 -18000 1 EASST}
+    {3167002800 -21600 0 EAST}
+    {3174868800 -18000 1 EASST}
+    {3198452400 -21600 0 EAST}
+    {3206318400 -18000 1 EASST}
+    {3230506800 -21600 0 EAST}
+    {3238372800 -18000 1 EASST}
+    {3261956400 -21600 0 EAST}
+    {3269822400 -18000 1 EASST}
+    {3293406000 -21600 0 EAST}
+    {3301272000 -18000 1 EASST}
+    {3324855600 -21600 0 EAST}
+    {3332721600 -18000 1 EASST}
+    {3356305200 -21600 0 EAST}
+    {3364171200 -18000 1 EASST}
+    {3387754800 -21600 0 EAST}
+    {3396225600 -18000 1 EASST}
+    {3419809200 -21600 0 EAST}
+    {3427675200 -18000 1 EASST}
+    {3451258800 -21600 0 EAST}
+    {3459124800 -18000 1 EASST}
+    {3482708400 -21600 0 EAST}
+    {3490574400 -18000 1 EASST}
+    {3514158000 -21600 0 EAST}
+    {3522024000 -18000 1 EASST}
+    {3545607600 -21600 0 EAST}
+    {3553473600 -18000 1 EASST}
+    {3577057200 -21600 0 EAST}
+    {3585528000 -18000 1 EASST}
+    {3609111600 -21600 0 EAST}
+    {3616977600 -18000 1 EASST}
+    {3640561200 -21600 0 EAST}
+    {3648427200 -18000 1 EASST}
+    {3672010800 -21600 0 EAST}
+    {3679876800 -18000 1 EASST}
+    {3703460400 -21600 0 EAST}
+    {3711326400 -18000 1 EASST}
+    {3734910000 -21600 0 EAST}
+    {3743380800 -18000 1 EASST}
+    {3766964400 -21600 0 EAST}
+    {3774830400 -18000 1 EASST}
+    {3798414000 -21600 0 EAST}
+    {3806280000 -18000 1 EASST}
+    {3829863600 -21600 0 EAST}
+    {3837729600 -18000 1 EASST}
+    {3861313200 -21600 0 EAST}
+    {3869179200 -18000 1 EASST}
+    {3892762800 -21600 0 EAST}
+    {3900628800 -18000 1 EASST}
+    {3924212400 -21600 0 EAST}
+    {3932683200 -18000 1 EASST}
+    {3956266800 -21600 0 EAST}
+    {3964132800 -18000 1 EASST}
+    {3987716400 -21600 0 EAST}
+    {3995582400 -18000 1 EASST}
+    {4019166000 -21600 0 EAST}
+    {4027032000 -18000 1 EASST}
+    {4050615600 -21600 0 EAST}
+    {4058481600 -18000 1 EASST}
+    {4082065200 -21600 0 EAST}
+    {4089931200 -18000 1 EASST}
 }
index b8f34a5..3e4bc3a 100644 (file)
 
 if {$::tcl_platform(platform) eq "windows"} {
     # Windows style - any but a unicode space char
-    set ::tcl_wordchars {\S}
-    set ::tcl_nonwordchars {\s}
+    if {![info exists ::tcl_wordchars]} {
+       set ::tcl_wordchars {\S}
+    }
+    if {![info exists ::tcl_nonwordchars]} {
+       set ::tcl_nonwordchars {\s}
+    }
 } else {
     # Motif style - any unicode word char (number, letter, or underscore)
-    set ::tcl_wordchars {\w}
-    set ::tcl_nonwordchars {\W}
+    if {![info exists ::tcl_wordchars]} {
+       set ::tcl_wordchars {\w}
+    }
+    if {![info exists ::tcl_nonwordchars]} {
+       set ::tcl_nonwordchars {\W}
+    }
 }
 
 # Arrange for caches of the real matcher REs to be kept, which enables the REs
index efacdec..ff430e9 100755 (executable)
@@ -2331,7 +2331,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 TCL_VERSION=8.6
 TCL_MAJOR_VERSION=8
 TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".5"
+TCL_PATCH_LEVEL=".6"
 VERSION=${TCL_VERSION}
 
 EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
similarity index 99%
rename from pkgs/itcl4.0.4/Makefile.in
rename to pkgs/itcl4.0.5/Makefile.in
index 4183474..24d8e92 100644 (file)
@@ -144,6 +144,7 @@ TCLSH               = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
 #WISH          = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
 
 SHARED_BUILD   = @SHARED_BUILD@
+STUBS_BUILD    = @STUBS_BUILD@
 
 INCLUDES       = @PKG_INCLUDES@ @TCL_INCLUDES@
 
@@ -312,10 +313,10 @@ dist-clean:
 
 dist: dist-clean doc
        $(INSTALL_DATA_DIR) $(DIST_DIR)
-       cp -p $(srcdir)/license* $(srcdir)/aclocal.m4 $(srcdir)/configure \
+       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
+       chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac
 
        $(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
        cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
similarity index 100%
rename from pkgs/itcl4.0.4/README
rename to pkgs/itcl4.0.5/README
similarity index 100%
rename from pkgs/itcl4.0.4/TODO
rename to pkgs/itcl4.0.5/TODO
similarity index 99%
rename from pkgs/itcl4.0.4/configure
rename to pkgs/itcl4.0.5/configure
index 5cef3e3..39a994b 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for itcl 4.0.4.
+# Generated by GNU Autoconf 2.69 for itcl 4.0.5.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='itcl'
 PACKAGE_TARNAME='itcl'
-PACKAGE_VERSION='4.0.4'
-PACKAGE_STRING='itcl 4.0.4'
+PACKAGE_VERSION='4.0.5'
+PACKAGE_STRING='itcl 4.0.5'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -655,6 +655,7 @@ CFLAGS_DEBUG
 RC
 CELIB_DIR
 AR
+STUBS_BUILD
 SHARED_BUILD
 TCL_THREADS
 TCL_TOP_DIR_NATIVE
@@ -753,6 +754,7 @@ with_tcl
 with_tclinclude
 enable_threads
 enable_shared
+enable_stubs
 enable_64bit
 enable_64bit_vis
 enable_rpath
@@ -1309,7 +1311,7 @@ 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 4.0.4 to adapt to many kinds of systems.
+\`configure' configures itcl 4.0.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1370,7 +1372,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of itcl 4.0.4:";;
+     short | recursive ) echo "Configuration of itcl 4.0.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1380,6 +1382,8 @@ Optional Features:
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --enable-threads        build with threads
   --enable-shared         build and link with shared libraries (default: on)
+  --enable-stubs          build and link with stub libraries. Always true for
+                          shared builds (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)
@@ -1470,7 +1474,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-itcl configure 4.0.4
+itcl configure 4.0.5
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1889,7 +1893,7 @@ 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 itcl $as_me 4.0.4, which was
+It was created by itcl $as_me 4.0.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2247,7 +2251,7 @@ 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.9"
+    TEA_VERSION="3.10"
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
 $as_echo_n "checking for correct TEA configuration... " >&6; }
@@ -2255,12 +2259,12 @@ $as_echo_n "checking for correct TEA configuration... " >&6; }
        as_fn_error $? "
 The PACKAGE_NAME variable must be defined by your TEA configure.ac" "$LINENO" 5
     fi
-    if test x"3.9" = x ; then
+    if test x"3.10" = x ; then
        as_fn_error $? "
 TEA version not specified." "$LINENO" 5
-    elif test "3.9" != "${TEA_VERSION}" ; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&5
-$as_echo "warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&6; }
+    elif test "3.10" != "${TEA_VERSION}" ; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: warning: requested TEA version \"3.10\", have \"${TEA_VERSION}\"" >&5
+$as_echo "warning: requested TEA version \"3.10\", have \"${TEA_VERSION}\"" >&6; }
     else
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (TEA ${TEA_VERSION})" >&5
 $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
@@ -3519,10 +3523,15 @@ _ACEOF
 
 
 
-if test "${TCL_VERSION}" != "8.6"; then
+if test "${TCL_MAJOR_VERSION}" -ne 8; then
     as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
-Itcl ${PACKAGE_VERSION} needs Tcl 8.6.
-Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6." "$LINENO" 5
+Itcl ${PACKAGE_VERSION} needs Tcl 8.6 or higher.
+Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6+." "$LINENO" 5
+fi
+if test "${TCL_MINOR_VERSION}" -lt 6; then
+    as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
+Itcl ${PACKAGE_VERSION} needs Tcl 8.6 or higher.
+Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6+." "$LINENO" 5
 fi
 
 #-----------------------------------------------------------------------
@@ -6095,23 +6104,40 @@ $as_echo "$as_me: WARNING:
 $as_echo_n "checking how to build libraries... " >&6; }
     # Check whether --enable-shared was given.
 if test "${enable_shared+set}" = set; then :
-  enableval=$enable_shared; tcl_ok=$enableval
+  enableval=$enable_shared; shared_ok=$enableval
 else
-  tcl_ok=yes
+  shared_ok=yes
 fi
 
 
     if test "${enable_shared+set}" = set; then
        enableval="$enable_shared"
-       tcl_ok=$enableval
+       shared_ok=$enableval
     else
-       tcl_ok=yes
+       shared_ok=yes
+    fi
+
+    # Check whether --enable-stubs was given.
+if test "${enable_stubs+set}" = set; then :
+  enableval=$enable_stubs; stubs_ok=$enableval
+else
+  stubs_ok=yes
+fi
+
+
+    if test "${enable_stubs+set}" = set; then
+       enableval="$enable_stubs"
+       stubs_ok=$enableval
+    else
+       stubs_ok=yes
     fi
 
-    if test "$tcl_ok" = "yes" ; then
+    # Stubs are always enabled for shared builds
+    if test "$shared_ok" = "yes" ; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
 $as_echo "shared" >&6; }
        SHARED_BUILD=1
+        STUBS_BUILD=1
     else
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
 $as_echo "static" >&6; }
@@ -6119,10 +6145,30 @@ $as_echo "static" >&6; }
 
 $as_echo "#define STATIC_BUILD 1" >>confdefs.h
 
+        if test "$stubs_ok" = "yes" ; then
+          STUBS_BUILD=1
+        else
+          STUBS_BUILD=0
+        fi
+    fi
+    if test "${STUBS_BUILD}" = "1" ; then
+
+$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
+
+
+$as_echo "#define USE_TCLOO_STUBS 1" >>confdefs.h
+
+      if test "${TEA_WINDOWINGSYSTEM}" != ""; then
+
+$as_echo "#define USE_TK_STUBS 1" >>confdefs.h
+
+      fi
     fi
 
 
 
+
+
 #--------------------------------------------------------------------
 # This macro figures out what flags to use with the compiler/linker
 # when building shared/static debug/optimized objects.  This information
@@ -8748,20 +8794,6 @@ 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.
-#--------------------------------------------------------------------
-
-
-$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
-
-
-$as_echo "#define USE_TCLOO_STUBS 1" >>confdefs.h
-
-
-#--------------------------------------------------------------------
 # 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.
@@ -8896,7 +8928,15 @@ $as_echo_n "checking for tclsh... " >&6; }
     if test -f "${TCL_BIN_DIR}/Makefile" ; then
         # tclConfig.sh is in Tcl build directory
         if test "${TEA_PLATFORM}" = "windows"; then
+          if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" ; then
             TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}"
+          fi
         else
             TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
         fi
@@ -9518,7 +9558,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by itcl $as_me 4.0.4, which was
+This file was extended by itcl $as_me 4.0.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9571,7 +9611,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-itcl config.status 4.0.4
+itcl config.status 4.0.5
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
similarity index 92%
rename from pkgs/itcl4.0.4/configure.in
rename to pkgs/itcl4.0.5/configure.ac
index da9c88c..5b27305 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash -norc
 #--------------------------------------------------------------------
-# Sample configure.in for Tcl Extensions.  The only places you should
+# Sample configure.ac for Tcl Extensions.  The only places you should
 # need to modify this file are marked by the string __CHANGE__
 #--------------------------------------------------------------------
 
@@ -10,7 +10,7 @@
 # so you can encode the package version directly into the source files.
 #-----------------------------------------------------------------------
 
-AC_INIT([itcl], [4.0.4])
+AC_INIT([itcl], [4.0.5])
 
 #--------------------------------------------------------------------
 # Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -18,7 +18,7 @@ AC_INIT([itcl], [4.0.4])
 # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
 #--------------------------------------------------------------------
 
-TEA_INIT([3.9])
+TEA_INIT([3.10])
 
 AC_PROG_LN_S
 CONFIG_CLEAN_FILES=
@@ -39,10 +39,15 @@ AC_CONFIG_AUX_DIR(tclconfig)
 TEA_PATH_TCLCONFIG
 TEA_LOAD_TCLCONFIG
 
-if test "${TCL_VERSION}" != "8.6"; then
+if test "${TCL_MAJOR_VERSION}" -ne 8; then
     AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
-Itcl ${PACKAGE_VERSION} needs Tcl 8.6.
-Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6.])
+Itcl ${PACKAGE_VERSION} needs Tcl 8.6 or higher.
+Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6+.])
+fi
+if test "${TCL_MINOR_VERSION}" -lt 6; then
+    AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
+Itcl ${PACKAGE_VERSION} needs Tcl 8.6 or higher.
+Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6+.])
 fi
 
 #-----------------------------------------------------------------------
@@ -191,16 +196,6 @@ AC_CHECK_TYPE([intptr_t], [
 ])
 
 #--------------------------------------------------------------------
-# 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.
-#--------------------------------------------------------------------
-
-AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
-AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO 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.
similarity index 98%
rename from pkgs/itcl4.0.4/generic/itcl.h
rename to pkgs/itcl4.0.5/generic/itcl.h
index 5d60ce4..b7872a0 100644 (file)
@@ -82,10 +82,10 @@ extern "C" {
 #define ITCL_MAJOR_VERSION     4
 #define ITCL_MINOR_VERSION     0
 #define ITCL_RELEASE_LEVEL      TCL_FINAL_RELEASE
-#define ITCL_RELEASE_SERIAL     4
+#define ITCL_RELEASE_SERIAL     5
 
 #define ITCL_VERSION            "4.0"
-#define ITCL_PATCH_LEVEL        "4.0.4"
+#define ITCL_PATCH_LEVEL        "4.0.5"
 
 
 /*
similarity index 99%
rename from pkgs/itcl4.0.4/generic/itclBase.c
rename to pkgs/itcl4.0.5/generic/itclBase.c
index c377fcf..f9188f8 100644 (file)
@@ -290,8 +290,7 @@ Initialize (
     Tcl_InitObjHashTable(&infoPtr->nameClasses);
     Tcl_InitHashTable(&infoPtr->namespaceClasses, TCL_ONE_WORD_KEYS);
     Tcl_InitHashTable(&infoPtr->procMethods, TCL_ONE_WORD_KEYS);
-    Tcl_InitObjHashTable(&infoPtr->instances);
-    Tcl_InitHashTable(&infoPtr->objectInstances, TCL_ONE_WORD_KEYS);
+    Tcl_InitHashTable(&infoPtr->instances, TCL_STRING_KEYS);
     Tcl_InitObjHashTable(&infoPtr->classTypes);
     infoPtr->ensembleInfo = (EnsembleInfo *)ckalloc(sizeof(EnsembleInfo));
     memset(infoPtr->ensembleInfo, 0, sizeof(EnsembleInfo));
similarity index 97%
rename from pkgs/itcl4.0.4/generic/itclBuiltin.c
rename to pkgs/itcl4.0.5/generic/itclBuiltin.c
index 4357b7e..03f5760 100644 (file)
@@ -3142,7 +3142,7 @@ Itcl_BiCallInstanceCmd(
     }
 
     hPtr = Tcl_FindHashEntry(&contextIclsPtr->infoPtr->instances,
-            (char *)objv[1]);
+            Tcl_GetString(objv[1]));
     if (hPtr == NULL) {
        Tcl_AppendResult(interp,
                "no such instanceName \"",
@@ -3209,7 +3209,7 @@ Itcl_BiGetInstanceVarCmd(
     }
 
     hPtr = Tcl_FindHashEntry(&contextIclsPtr->infoPtr->instances,
-            (char *)objv[1]);
+            Tcl_GetString(objv[1]));
     if (hPtr == NULL) {
        Tcl_AppendResult(interp,
                "no such instanceName \"",
@@ -3297,8 +3297,6 @@ Itcl_BiMyMethodCmd(
     int objc,                /* number of arguments */
     Tcl_Obj *const objv[])   /* argument objects */
 {
-    Tcl_HashEntry *hPtr;
-    Tcl_Obj *objPtr;
     Tcl_Obj *resultPtr;
     int i;
     ItclClass *contextIclsPtr;
@@ -3314,18 +3312,11 @@ Itcl_BiMyMethodCmd(
         return TCL_ERROR;
     }
     if (contextIoPtr != NULL) {
-        hPtr =Tcl_FindHashEntry(&contextIclsPtr->infoPtr->objectInstances,
-               (char *)contextIoPtr);
-       if (hPtr == NULL) {
-           Tcl_AppendResult(interp, "cannot find context object",
-                   " in objectInstances", NULL);
-            return TCL_ERROR;
-       }
-       objPtr = Tcl_GetHashValue(hPtr);
        resultPtr = Tcl_NewListObj(0, NULL);
        Tcl_ListObjAppendElement(interp, resultPtr,
                Tcl_NewStringObj("::itcl::builtin::callinstance", -1));
-       Tcl_ListObjAppendElement(interp, resultPtr, objPtr);
+       Tcl_ListObjAppendElement(interp, resultPtr, Tcl_NewStringObj(
+               (Tcl_GetObjectNamespace(contextIoPtr->oPtr))->fullName, -1));
        for (i = 1; i < objc; i++) {
            Tcl_ListObjAppendElement(interp, resultPtr, objv[i]);
        }
@@ -3458,7 +3449,6 @@ Itcl_BiMyVarCmd(
     int objc,                /* number of arguments */
     Tcl_Obj *const objv[])   /* argument objects */
 {
-    Tcl_HashEntry *hPtr;
     Tcl_Obj *resultPtr;
     ItclClass *contextIclsPtr;
     ItclObject *contextIoPtr;
@@ -3473,13 +3463,6 @@ Itcl_BiMyVarCmd(
         return TCL_ERROR;
     }
     if (contextIoPtr != NULL) {
-        hPtr =Tcl_FindHashEntry(&contextIclsPtr->infoPtr->objectInstances,
-               (char *)contextIoPtr);
-       if (hPtr == NULL) {
-           Tcl_AppendResult(interp, "cannot find context object",
-                   " in objectInstances", NULL);
-            return TCL_ERROR;
-       }
         resultPtr = Tcl_NewStringObj(Tcl_GetString(contextIoPtr->varNsNamePtr),
                -1);
        Tcl_AppendToObj(resultPtr, "::", -1);
@@ -3675,18 +3658,6 @@ Itcl_BiKeepComponentOptionCmd(
     int objc,                /* number of arguments */
     Tcl_Obj *const objv[])   /* argument objects */
 {
-#ifdef NOTDEF
-    Tcl_HashEntry *hPtr;
-    Tcl_HashEntry *hPtr2;
-    Tcl_Obj *objPtr;
-    ItclClass *iclsPtr;
-    ItclObject *ioPtr;
-    ItclDelegatedOption *idoPtr;
-    ItclComponent *icPtr;
-    const char *val;
-    int idx;
-    int isNew;
-#endif
     int result;
     ItclObjectInfo *infoPtr = (ItclObjectInfo*)clientData;
 
@@ -3700,73 +3671,6 @@ Itcl_BiKeepComponentOptionCmd(
     }
     result =  Tcl_EvalObjv(interp, objc, objv, 0);
     return result;
-#ifdef NOTDEF
-    iclsPtr = NULL;
-    if (Itcl_GetContext(interp, &iclsPtr, &ioPtr) != TCL_OK) {
-        return TCL_ERROR;
-    }
-    if (objc < 3) {
-       Tcl_AppendResult(interp, "wrong # args, should be: ",
-               "keepcomponentoption component option ?option ...?", NULL);
-        return TCL_ERROR;
-    }
-    if (ioPtr != NULL) {
-        hPtr = Tcl_FindHashEntry(&ioPtr->objectComponents, (char *)objv[1]);
-        if (hPtr == NULL) {
-           Tcl_AppendResult(interp,
-                   "keepcomponentoption cannot find component \"",
-                   Tcl_GetString(objv[1]), "\"", NULL);
-           return TCL_ERROR;
-       }
-        icPtr = Tcl_GetHashValue(hPtr);
-       icPtr->haveKeptOptions = 1;
-       for (idx = 2; idx < objc; idx++) {
-           hPtr = Tcl_CreateHashEntry(&icPtr->keptOptions, (char *)objv[idx],
-                   &isNew);
-            if (isNew) {
-               Tcl_SetHashValue(hPtr, objv[idx]);
-           }
-           hPtr2 = Tcl_CreateHashEntry(&ioPtr->objectDelegatedOptions,
-                   (char *)objv[idx], &isNew);
-           if (isNew) {
-               idoPtr = (ItclDelegatedOption *)ckalloc(sizeof(
-                       ItclDelegatedOption));
-               memset(idoPtr, 0, sizeof(ItclDelegatedOption));
-               Tcl_InitObjHashTable(&idoPtr->exceptions);
-               idoPtr->namePtr = objv[idx];
-               Tcl_IncrRefCount(idoPtr->namePtr);
-               idoPtr->resourceNamePtr = NULL;
-               if (idoPtr->resourceNamePtr != NULL) {
-                   Tcl_IncrRefCount(idoPtr->resourceNamePtr);
-               }
-               idoPtr->classNamePtr = NULL;
-               if (idoPtr->classNamePtr != NULL) {
-                   Tcl_IncrRefCount(idoPtr->classNamePtr);
-               }
-               idoPtr->icPtr = icPtr;
-               idoPtr->ioptPtr = NULL;
-               Tcl_SetHashValue(hPtr2, idoPtr);
-                val = ItclGetInstanceVar(interp, Tcl_GetString(icPtr->namePtr),
-                       NULL, ioPtr, iclsPtr);
-               if (val != NULL) {
-                    objPtr = Tcl_NewStringObj(val, -1);
-                    Tcl_AppendToObj(objPtr, " cget ", -1);
-                    Tcl_AppendToObj(objPtr, Tcl_GetString(objv[idx]), -1);
-                    Tcl_IncrRefCount(objPtr);
-                    result = Tcl_EvalObjEx(interp, objPtr, 0);
-                    Tcl_DecrRefCount(objPtr);
-                   if (result == TCL_OK) {
-                       ItclSetInstanceVar(interp, "itcl_options",
-                               Tcl_GetString(objv[idx]),
-                               Tcl_GetStringResult(interp), ioPtr, iclsPtr);
-                   }
-                }
-            }
-        }
-        ItclAddClassComponentDictInfo(interp, iclsPtr, icPtr);
-    }
-    return TCL_OK;
-#endif
 }
 \f
 /*
similarity index 98%
rename from pkgs/itcl4.0.4/generic/itclClass.c
rename to pkgs/itcl4.0.5/generic/itclClass.c
index c381e3e..2f58e0e 100644 (file)
@@ -1083,6 +1083,7 @@ ItclFreeClass(
     Itcl_ListElem *elem;
     ItclVarLookup *vlookup;
     ItclCmdLookup *clookupPtr;
+    Tcl_Var var;
 
     iclsPtr = (ItclClass*)cdata;
     if (iclsPtr->flags & ITCL_CLASS_IS_FREED) {
@@ -1249,12 +1250,16 @@ ItclFreeClass(
     }
 
     /* FIXME !!!
-      free classCommons
       free contextCache
       free resolvePtr -- this is only needed for CallFrame Resolvers
                       -- not used at the moment
      */
 
+    FOREACH_HASH_VALUE(var, &iclsPtr->classCommons) {
+       Itcl_ReleaseVar(var);
+    }
+    Tcl_DeleteHashTable(&iclsPtr->classCommons);
+
     /*
      *  Free up the widget class name
      */
@@ -1866,32 +1871,6 @@ Itcl_BuildVirtualTables(
            vlookup->classVarInfoPtr = clientData2;
 #endif
 /* FIXME !!! should use for var lookup !! */
-#ifdef NOTDEF
-            /*
-             *  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 ((ivPtr->flags & ITCL_COMMON) != 0) {
-                nsPtr = (Namespace*)iclsPtr2->nsPtr;
-                hPtr = Tcl_FindHashEntry(&nsPtr->varTable, ivPtr->name);
-                assert(hPtr != NULL);
-
-                vlookup->var.common = (Tcl_Var)Tcl_GetHashValue(hPtr);
-            } 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 ((ivPtr->flags & ITCL_THIS_VAR) != 0) {
-                    vlookup->var.index = 0;
-                }
-                else {
-                    vlookup->var.index = iclsPtr->numInstanceVars++;
-                }
-            }
-#endif
 
             /*
              *  Create all possible names for this variable and enter
@@ -2204,24 +2183,6 @@ Itcl_CreateOption(
         return TCL_ERROR;
     }
 
-#ifdef NOTDEF
-    /*
-     *  If this option has some "config" code, try to capture
-     *  its implementation.
-     */
-    if (config) {
-        if (Itcl_CreateMemberCode(interp, iclsPtr, (char*)NULL, config,
-                &mCodePtr) != TCL_OK) {
-            Tcl_DeleteHashEntry(hPtr);
-            return TCL_ERROR;
-        }
-        Itcl_PreserveData((ClientData)mCodePtr);
-        Itcl_EventuallyFree((ClientData)mCodePtr, Itcl_DeleteMemberCode);
-    } else {
-        mCodePtr = NULL;
-    }
-#endif
-        
     iclsPtr->numOptions++;
     ioptPtr->iclsPtr = iclsPtr;
     ioptPtr->codePtr = mCodePtr;
similarity index 99%
rename from pkgs/itcl4.0.4/generic/itclCmd.c
rename to pkgs/itcl4.0.5/generic/itclCmd.c
index 8c1c8a2..16de7fe 100644 (file)
@@ -1878,6 +1878,7 @@ Itcl_AddComponentCmd(
     hPtr = Tcl_CreateHashEntry(&contextIoPtr->objectVariables,
             (char *)ivPtr, &isNew);
     if (isNew) {
+       Itcl_PreserveVar(varPtr);
         Tcl_SetHashValue(hPtr, varPtr);
     } else {
     }
similarity index 98%
rename from pkgs/itcl4.0.4/generic/itclEnsemble.c
rename to pkgs/itcl4.0.5/generic/itclEnsemble.c
index bcc79bd..fb833f5 100644 (file)
@@ -119,30 +119,6 @@ static void ComputeMinChars (Ensemble *ensData, int pos);
 static EnsembleParser* GetEnsembleParser (Tcl_Interp *interp);
 static void DeleteEnsParser (ClientData clientData, Tcl_Interp* interp);
 
-#ifdef NOTDEF
-static void
-DumpEnsemble(
-    Tcl_Interp *interp,
-    Ensemble *ensData)
-{
-    Ensemble *ensData2;
-    int i;
-
-    ensData2 = ensData;
-    while (1) {
-        fprintf(stderr, "ENS!%s!%d!\n",
-               Tcl_GetCommandName(interp, ensData2->cmdPtr), ensData2->numParts);
-        for (i=0; i<ensData2->numParts; i++) {
-            fprintf(stderr, "  %d!%s!\n", i, ensData2->parts[i]->name);
-        }
-        if (ensData2->parent == NULL) {
-            break;
-        }
-        ensData2 = ensData2->parent->ensemble;
-    }
-}
-#endif
-
 \f
 /*
  *----------------------------------------------------------------------
@@ -591,11 +567,6 @@ Itcl_GetEnsembleUsageForObj(
      *  back to the command word for the entire ensemble.
      */
     chainObj = ensObjPtr;
-#ifdef NOTDEF
-    while (chainObj && chainObj->typePtr == &itclEnsInvocType) {
-         chainObj = (Tcl_Obj*)chainObj->internalRep.twoPtrValue.ptr2;
-    }
-#endif
 
     if (chainObj) {
         cmd = Tcl_GetCommandFromObj(interp, chainObj);
@@ -1794,8 +1765,6 @@ Itcl_EnsembleCmd(
      *  Otherwise, the offending command is reported twice.
      */
     if (status == TCL_ERROR) {
-#ifdef NOTDEF
-#else
        /* no longer needed, no extra interpreter !! */
         const char *errInfo = Tcl_GetVar2(ensInfo->parser, "::errorInfo",
             (char*)NULL, TCL_GLOBAL_ONLY);
@@ -1803,7 +1772,6 @@ Itcl_EnsembleCmd(
         if (errInfo) {
             Tcl_AddObjErrorInfo(interp, (const char *)errInfo, -1);
         }
-#endif
 
         if (objc == 3) {
            Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
@@ -1864,32 +1832,7 @@ GetEnsembleParser(
     ensInfo->parser = Tcl_CreateInterp();
     ensInfo->ensData = NULL;
 
-#ifdef NOTDEF
-    /*
-     *  Remove all namespaces and all normal commands from the
-     *  parser interpreter.
-     */
-    nsPtr = 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);
-    }
-
-#else
     Tcl_DeleteNamespace(Tcl_GetGlobalNamespace(ensInfo->parser));
-#endif
     /*
      *  Add the allowed commands to the parser interpreter:
      *  part, delete, ensemble
similarity index 97%
rename from pkgs/itcl4.0.4/generic/itclHelpers.c
rename to pkgs/itcl4.0.5/generic/itclHelpers.c
index 21bdf56..63a6b2f 100644 (file)
@@ -372,53 +372,6 @@ ItclEnsembleSubCmd(
 \f
 /*
  * ------------------------------------------------------------------------
- *  ItclTraceUnsetVar()
- * ------------------------------------------------------------------------
- */
-
-char *
-ItclTraceUnsetVar(
-    ClientData clientData,
-    Tcl_Interp *interp,
-    const char *name1,
-    const char *name2,
-    int flags)
-{
-#ifdef NOTDEF
-    IctlVarTraceInfo *tracePtr;
-    Tcl_HashEntry *hPtr;
-#endif
-
-    if (name2 != NULL) {
-        /* unsetting of an array element nothing to do */
-       return NULL;
-    }
-    /* also when unsetting variables, they stay alive until the class
-     * or object is teared down!!
-     */
-#ifdef NOTDEF
-    tracePtr = (IctlVarTraceInfo *)clientData;
-    if (tracePtr->flags & ITCL_TRACE_CLASS) {
-        hPtr = Tcl_FindHashEntry(&tracePtr->iclsPtr->classCommons,
-               (char *)tracePtr->ivPtr);
-       if (hPtr != NULL) {
-           Tcl_DeleteHashEntry(hPtr);
-       }
-    }
-    if (tracePtr->flags & ITCL_TRACE_OBJECT) {
-        hPtr = Tcl_FindHashEntry(&tracePtr->ioPtr->objectVariables,
-               (char *)tracePtr->ivPtr);
-       if (hPtr != NULL) {
-           Tcl_DeleteHashEntry(hPtr);
-       }
-    }
-    ckfree((char *)tracePtr);
-#endif
-    return NULL;
-}
-\f
-/*
- * ------------------------------------------------------------------------
  *  ItclCapitalize()
  * ------------------------------------------------------------------------
  */
@@ -481,6 +434,7 @@ AddDictEntry(
     }
     keyPtr = Tcl_NewStringObj(keyStr, -1);
     if (Tcl_DictObjPut(interp, dictPtr, keyPtr, valuePtr) != TCL_OK) {
+       Tcl_DecrRefCount(keyPtr);
         return TCL_ERROR;
     }
     return TCL_OK;
@@ -742,8 +696,8 @@ ItclAddObjectsDictInfo(
     }
     objPtr = Tcl_NewObj();
     Tcl_GetCommandFullName(interp, ioPtr->accessCmd, objPtr);
-    Tcl_IncrRefCount(objPtr);
     if (AddDictEntry(interp, valuePtr2, "-command", objPtr) != TCL_OK) {
+       Tcl_DecrRefCount(objPtr);
         return TCL_ERROR;
     }
     keyPtr = ioPtr->namePtr;
@@ -751,9 +705,11 @@ ItclAddObjectsDictInfo(
         return TCL_ERROR;
     }
     if (newValue1) {
-        if (Tcl_DictObjPut(interp, dictPtr, keyPtr1, valuePtr1) != TCL_OK) {
-            return TCL_ERROR;
-        }
+       /* Cannot fail. Screened non-dicts earlier. */
+        Tcl_DictObjPut(interp, dictPtr, keyPtr1, valuePtr1);
+    } else {
+       /* Don't leak the key val... */
+       Tcl_DecrRefCount(keyPtr1);
     }
     Tcl_SetVar2Ex(interp, ITCL_NAMESPACE"::internal::dicts::objects",
             NULL, dictPtr, 0);
@@ -785,28 +741,36 @@ ItclDeleteObjectsDictInfo(
     }
     keyPtr1 = Tcl_NewStringObj("instances", -1);
     if (Tcl_DictObjGet(interp, dictPtr, keyPtr1, &valuePtr) != TCL_OK) {
+       Tcl_DecrRefCount(keyPtr1);
         return TCL_ERROR;
     }
     if (valuePtr == NULL) {
        /* looks like no object has been registered yet
         * so ignore and return OK */
+       Tcl_DecrRefCount(keyPtr1);
         return TCL_OK;
     }
     keyPtr = ioPtr->namePtr;
     if (Tcl_DictObjGet(interp, valuePtr, keyPtr, &valuePtr1) != TCL_OK) {
+       Tcl_DecrRefCount(keyPtr1);
         return TCL_ERROR;
     }
     if (valuePtr1 == NULL) {
        /* looks like the object has not been constructed successfully
         * so ignore and return OK */
+       Tcl_DecrRefCount(keyPtr1);
         return TCL_OK;
     }
     if (Tcl_DictObjRemove(interp, valuePtr, keyPtr) != TCL_OK) {
+       Tcl_DecrRefCount(keyPtr1);
         return TCL_ERROR;
     }
     if (Tcl_DictObjPut(interp, dictPtr, keyPtr1, valuePtr) != TCL_OK) {
+       /* This is very likely impossible. non-dict already screened. */
+       Tcl_DecrRefCount(keyPtr1);
         return TCL_ERROR;
     }
+    Tcl_DecrRefCount(keyPtr1);
     Tcl_SetVar2Ex(interp, ITCL_NAMESPACE"::internal::dicts::objects",
             NULL, dictPtr, 0);
     return TCL_OK;
similarity index 98%
rename from pkgs/itcl4.0.4/generic/itclInt.h
rename to pkgs/itcl4.0.5/generic/itclInt.h
index 0e0f07e..f6a4244 100644 (file)
@@ -149,7 +149,7 @@ typedef struct ItclObjectInfo {
     Tcl_HashTable namespaceClasses; /* maps from nsPtr to iclsPtr */
     Tcl_HashTable procMethods;      /* maps from procPtr to mFunc */
     Tcl_HashTable instances;        /* maps from instanceNumber to ioPtr */
-    Tcl_HashTable objectInstances;  /* maps from ioPtr to instanceNumber */
+    Tcl_HashTable unused8;          /* maps from ioPtr to instanceNumber */
     Tcl_HashTable unused;           /* Obsolete field */
     Tcl_HashTable classTypes;       /* maps from class type i.e. "widget"
                                      * to define value i.e. ITCL_WIDGET */
@@ -182,7 +182,7 @@ typedef struct ItclObjectInfo {
     Tcl_Obj **unparsedObjv;         /* options not parsed by
                                        ItclExtendedConfigure/-Cget function */
     int functionFlags;              /* used for creating of ItclMemberCode */
-    int numInstances;               /* used for having a unique key for objects
+    int unused7;               /* used for having a unique key for objects
                                      * for use in mytypemethod etc. */
     struct ItclDelegatedOption *currIdoPtr;
                                     /* the current delegated option info */
@@ -587,16 +587,6 @@ typedef struct ItclMethodVariable {
     Tcl_Obj *callbackPtr;
 } ItclMethodVariable;
 
-typedef struct IctlVarTraceInfo {
-    int flags;
-    ItclVariable* ivPtr;
-    ItclClass *iclsPtr;
-    ItclObject *ioPtr;
-} IctlVarTraceInfo;
-
-#define ITCL_TRACE_CLASS               0x01
-#define ITCL_TRACE_OBJECT              0x02
-
 #define VAR_TYPE_VARIABLE      1
 #define VAR_TYPE_COMMON        2
 
@@ -727,8 +717,6 @@ MODULE_SCOPE void ItclDeleteObjectVariablesNamespace(Tcl_Interp *interp,
 MODULE_SCOPE void ItclDeleteClassVariablesNamespace(Tcl_Interp *interp,
         ItclClass *iclsPtr);
 MODULE_SCOPE int ItclInfoInit(Tcl_Interp *interp);
-MODULE_SCOPE char * ItclTraceUnsetVar(ClientData clientData, Tcl_Interp *interp,
-       const char *name1, const char *name2, int flags);
 
 struct Tcl_ResolvedVarInfo;
 MODULE_SCOPE int Itcl_ClassCmdResolver(Tcl_Interp *interp, const char* name,
similarity index 96%
rename from pkgs/itcl4.0.4/generic/itclMigrate2TclCore.c
rename to pkgs/itcl4.0.5/generic/itclMigrate2TclCore.c
index b28e5be..68eaf39 100644 (file)
@@ -64,10 +64,28 @@ Tcl_NewNamespaceVar(
     varPtr = TclVarHashCreateVar(&((Namespace *)nsPtr)->varTable,
             varName, &new);
     TclSetVarNamespaceVar(varPtr);
-    VarHashRefCount(varPtr)++;
     return (Tcl_Var)varPtr;
 }
 
+void
+Itcl_PreserveVar(
+    Tcl_Var var)
+{
+    Var *varPtr = (Var *)var;
+
+    VarHashRefCount(varPtr)++;
+}
+
+void
+Itcl_ReleaseVar(
+    Tcl_Var var)
+{
+    Var *varPtr = (Var *)var;
+
+    VarHashRefCount(varPtr)--;
+    TclCleanupVar(varPtr, NULL);
+}
+
 Tcl_CallFrame *
 Itcl_GetUplevelCallFrame(
     Tcl_Interp *interp,
similarity index 96%
rename from pkgs/itcl4.0.4/generic/itclMigrate2TclCore.h
rename to pkgs/itcl4.0.5/generic/itclMigrate2TclCore.h
index 0de66d6..012ea0b 100644 (file)
@@ -75,6 +75,8 @@ typedef struct Tcl_Proc_ *Tcl_Proc;
 
 MODULE_SCOPE Tcl_Var Tcl_NewNamespaceVar(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
        const char *varName);
+MODULE_SCOPE void Itcl_PreserveVar(Tcl_Var var);
+MODULE_SCOPE void Itcl_ReleaseVar(Tcl_Var var);
 MODULE_SCOPE int Itcl_IsCallFrameArgument(Tcl_Interp *interp, const char *name);
 MODULE_SCOPE int Itcl_GetCallVarFrameObjc(Tcl_Interp *interp);
 MODULE_SCOPE int Itcl_IsVarLink(Tcl_Var var);
similarity index 98%
rename from pkgs/itcl4.0.4/generic/itclObject.c
rename to pkgs/itcl4.0.5/generic/itclObject.c
index fb81f5a..d727659 100644 (file)
@@ -81,10 +81,21 @@ void
 ItclDeleteObjectMetadata(
     ClientData clientData)
 {
-    /*
-     * nothing to to yet, as there are only ItclClass or ItclObject pointers
-     * stored, which are freed elsewhere
-     */
+    ItclObject *ioPtr = (ItclObject *)clientData;
+    Tcl_HashEntry *hPtr;
+
+    if (ioPtr == NULL) return;         /* Safety */
+    if (ioPtr->oPtr == NULL) return;   /* Safety */
+    
+    hPtr = Tcl_FindHashEntry(&ioPtr->infoPtr->instances,
+       (Tcl_GetObjectNamespace(ioPtr->oPtr))->fullName);
+
+    if (hPtr == NULL) return;
+
+    if (clientData != Tcl_GetHashValue(hPtr)) {
+       Tcl_Panic("invalid instances entry");
+    }
+    Tcl_DeleteHashEntry(hPtr);
 }
 \f
 /*
@@ -208,7 +219,6 @@ ItclCreateObject(
     char unique[256];    /* buffer used for unique part of object names */
     int newEntry;
     ItclResolveInfo *resolveInfoPtr;
-    char str[100];
     /* objv[1]: class name */
     /* objv[2]: class full name */
     /* objv[3]: object name */
@@ -450,18 +460,12 @@ ItclCreateObject(
         (char*)ioPtr, &newEntry);
     Tcl_SetHashValue(hPtr, (ClientData)ioPtr);
 
-    /* make the object instance known, for use as unique key if the object */
-    /* is renamed. Used by mytypemethod etc. */
-    sprintf(str, "ItclInst%d", iclsPtr->infoPtr->numInstances);
-    /* FIXME need to free that when deleting object and to remove the entries!! */
-    objPtr = Tcl_NewStringObj(str, -1);
+    /* Use the TclOO object namespaces as a unique key in case the
+     * object is renamed. Used by mytypemethod, etc. */
+
     hPtr = Tcl_CreateHashEntry(&iclsPtr->infoPtr->instances,
-        (char*)objPtr, &newEntry);
+       (Tcl_GetObjectNamespace(ioPtr->oPtr))->fullName, &newEntry);
     Tcl_SetHashValue(hPtr, (ClientData)ioPtr);
-    hPtr = Tcl_CreateHashEntry(&iclsPtr->infoPtr->objectInstances,
-        (char*)ioPtr, &newEntry);
-    Tcl_SetHashValue(hPtr, (ClientData)objPtr);
-    iclsPtr->infoPtr->numInstances++;
 
     /*
      *  Now construct the object.  Look for a constructor in the
@@ -956,7 +960,6 @@ ItclInitObjectVariables(
            vlookup = Tcl_GetHashValue(hPtr2);
 #endif
            if ((ivPtr->flags & ITCL_COMMON) == 0) {
-                IctlVarTraceInfo *traceInfoPtr;
 #ifndef NEW_PROTO_RESOLVER
                 varPtr = Tcl_NewNamespaceVar(interp, varNsPtr,
                         Tcl_GetString(ivPtr->namePtr));
@@ -968,19 +971,10 @@ ItclInitObjectVariables(
                hPtr2 = Tcl_CreateHashEntry(&ioPtr->objectVariables,
                        (char *)ivPtr, &isNew);
                if (isNew) {
+                   Itcl_PreserveVar(varPtr);
                    Tcl_SetHashValue(hPtr2, varPtr);
                } else {
                }
-                traceInfoPtr = (IctlVarTraceInfo *)ckalloc(
-                       sizeof(IctlVarTraceInfo));
-                memset (traceInfoPtr, 0, sizeof(IctlVarTraceInfo));
-                traceInfoPtr->flags = ITCL_TRACE_OBJECT;
-                traceInfoPtr->ioPtr = ioPtr;
-                traceInfoPtr->iclsPtr = iclsPtr2;
-                traceInfoPtr->ivPtr = ivPtr;
-                Tcl_TraceVar2(interp, Tcl_GetString(ivPtr->namePtr), NULL,
-                       TCL_TRACE_UNSETS, ItclTraceUnsetVar,
-                       (ClientData)traceInfoPtr);
                if (ivPtr->flags & (ITCL_THIS_VAR|ITCL_TYPE_VAR|
                        ITCL_SELF_VAR|ITCL_SELFNS_VAR|ITCL_WIN_VAR)) {
                     int isDone = 0;
@@ -1085,6 +1079,7 @@ ItclInitObjectVariables(
                    hPtr2 = Tcl_CreateHashEntry(&ioPtr->objectVariables,
                            (char *)ivPtr, &isNew);
                    if (isNew) {
+                       Itcl_PreserveVar(varPtr);
                        Tcl_SetHashValue(hPtr2, varPtr);
                    } else {
 #ifdef NEW_PROTO_RESOLVER
@@ -2168,18 +2163,6 @@ ItclTraceThisVar(
             Tcl_GetCommandFullName(contextIoPtr->iclsPtr->interp,
                 contextIoPtr->accessCmd, objPtr);
         }
-#ifdef NOTDEF
-       /* is there a trace handler necessary for "thiswidget"??
-        * right now the one for "this" is used !!
-        */
-           if (!isDone && (contextIoPtr->iclsPtr->flags & ITCL_WIDGET)) {
-               /* thiswidget variable */
-               Tcl_SetStringObj(objPtr, Tcl_GetCommandName(
-                       contextIoPtr->iclsPtr->interp,
-                       contextIoPtr->accessCmd), -1);
-               isDone = 1;
-           }
-#endif
         objName = Tcl_GetString(objPtr);
         Tcl_SetVar(interp, (const char *)name1, objName, 0);
 
@@ -2720,10 +2703,11 @@ static void
 ItclFreeObject(
     char * cdata)  /* object instance data */
 {
-    Tcl_HashEntry *hPtr;
+    FOREACH_HASH_DECLS;
     Tcl_HashSearch place;
     ItclCallContext *callContextPtr;
     ItclObject *ioPtr;
+    Tcl_Var var;
     
     ioPtr = (ItclObject*)cdata;
 
@@ -2761,6 +2745,10 @@ ItclFreeObject(
        Tcl_DeleteHashEntry(hPtr);
         ckfree((char *)callContextPtr);
     }
+    FOREACH_HASH_VALUE(var, &ioPtr->objectVariables) {
+       Itcl_ReleaseVar(var);
+    }
+
     Tcl_DeleteHashTable(&ioPtr->contextCache);
     Tcl_DeleteHashTable(&ioPtr->objectVariables);
     Tcl_DeleteHashTable(&ioPtr->objectOptions);
@@ -3850,13 +3838,6 @@ ItclInitExtendedClassOptions(
                if (ItclGetInstanceVar(interp, "itcl_options",
                        Tcl_GetString(ioptPtr->namePtr), ioPtr, iclsPtr)
                        == NULL) {
-#ifdef NOTDEF
-fprintf(stderr, "SET OPTION3!%s!\n", Tcl_GetString(ioptPtr->namePtr));
-                    ItclSetInstanceVar(interp, "itcl_options",
-                            Tcl_GetString(ioptPtr->namePtr),
-                            Tcl_GetString(ioptPtr->defaultValuePtr),
-                           ioPtr, iclsPtr);
-#endif
                }
             }
        }
similarity index 99%
rename from pkgs/itcl4.0.4/generic/itclParse.c
rename to pkgs/itcl4.0.5/generic/itclParse.c
index 5519cda..be25d05 100644 (file)
@@ -2005,7 +2005,6 @@ ItclInitClassCommon(
     Tcl_Var varPtr;
     int result;
     int isNew;
-    IctlVarTraceInfo *traceInfoPtr;
 
     result = TCL_OK;
     ivPtr->flags |= ITCL_COMMON;
@@ -2037,19 +2036,11 @@ ItclInitClassCommon(
     hPtr = Tcl_CreateHashEntry(&iclsPtr->classCommons, (char *)ivPtr,
             &isNew);
     if (isNew) {
+       Itcl_PreserveVar(varPtr);
         Tcl_SetHashValue(hPtr, varPtr);
     }
     result = Itcl_PushCallFrame(interp, &frame, commonNsPtr,
         /* isProcCallFrame */ 0);
-    traceInfoPtr = (IctlVarTraceInfo *)ckalloc(sizeof(IctlVarTraceInfo));
-    memset (traceInfoPtr, 0, sizeof(IctlVarTraceInfo));
-    traceInfoPtr->flags = ITCL_TRACE_CLASS;
-    traceInfoPtr->ioPtr = NULL;
-    traceInfoPtr->iclsPtr = ivPtr->iclsPtr;
-    traceInfoPtr->ivPtr = ivPtr;
-    Tcl_TraceVar2(interp, Tcl_GetString(ivPtr->namePtr), NULL,
-           TCL_TRACE_UNSETS, ItclTraceUnsetVar,
-           (ClientData)traceInfoPtr);
     Itcl_PopCallFrame(interp);
 
     /*
@@ -2886,10 +2877,6 @@ ItclCreateComponent(
 
     if (iclsPtr == NULL) {
        return TCL_OK;
-#ifdef NOTDEF
-       Tcl_AppendResult(interp, "INTERNAL ERROR in ItclCreateComponent, iclsPtr == NULL", NULL);
-        return TCL_ERROR;
-#endif
     }
     hPtr = Tcl_CreateHashEntry(&iclsPtr->components, (char *)componentPtr,
             &isNew);
@@ -3178,9 +3165,6 @@ ItclCreateDelegatedFunction(
     Tcl_Obj *exceptionsPtr,
     ItclDelegatedFunction **idmPtrPtr)
 {
-#ifdef NOTDEF
-    Tcl_HashEntry *hPtr;
-#endif
     ItclDelegatedFunction *idmPtr;
     const char **argv;
     int argc;
@@ -3211,16 +3195,6 @@ ItclCreateDelegatedFunction(
            objPtr = Tcl_NewStringObj(argv[i], -1);
            Tcl_CreateHashEntry(&idmPtr->exceptions, (char *)objPtr,
                    &isNew);
-#ifdef NOTDEF
-           hPtr2 = Tcl_FindHashEntry(&iclsPtr->functions, (char *)objPtr);
-/* FIXME !!! can only be done after a class/widget has been parsed completely !! */
-           if (hPtr2 == NULL) {
-               Tcl_AppendResult(interp, "no such method: \"",
-                       Tcl_GetString(objPtr), "\" found for delegation", NULL);
-               return TCL_ERROR;
-           }
-           Tcl_SetHashValue(hPtr, Tcl_GetHashValue(hPtr2));
-#endif
        }
     }
     if (idmPtrPtr != NULL) {
similarity index 99%
rename from pkgs/itcl4.0.4/generic/itclResolve.c
rename to pkgs/itcl4.0.5/generic/itclResolve.c
index 42aea80..02eb7fc 100644 (file)
@@ -365,12 +365,6 @@ Itcl_ClassVarResolver(
         hPtr = Tcl_FindHashEntry(&infoPtr->objects, (char *)contextIoPtr);
         if (hPtr == NULL) {
             continue;
-#ifdef NOTDEF
-           char str[20];
-           sprintf(str, "%p", contextIoPtr);
-           Tcl_AppendResult(interp, "contextIoPtr has vanished!!", str, NULL);
-            return TCL_ERROR;
-#endif
         }
         if (contextIoPtr->iclsPtr != vlookup->ivPtr->iclsPtr) {
            if (strcmp(Tcl_GetString(vlookup->ivPtr->namePtr), "this") == 0) {
similarity index 96%
rename from pkgs/itcl4.0.4/generic/itclTestRegisterC.c
rename to pkgs/itcl4.0.5/generic/itclTestRegisterC.c
index 3b5ef13..7489b89 100644 (file)
@@ -39,9 +39,6 @@ cArgFunc(
     int argc,
     const char **argv)
 {
-#ifdef NOTDEF
-    int i;
-#endif
     int result;
     ItclObjectInfo * infoPtr = NULL;
     ItclClass *iclsPtr = NULL;
@@ -76,12 +73,6 @@ cArgFunc(
       return TCL_ERROR;
     }
 
-#ifdef NOTDEF
-fprintf(stderr, "cArgFunc called:\n");
-for(i = 0; i<argc;i++) {
-    fprintf(stderr, "arg:%d:%s:\n", i, argv[i]);
-}
-#endif 
     /* try to create an object for a class as a test for calling a C function from
      * an Itcl class. See file CreateItclObjectWithC_example.tcl in library directory
      */
similarity index 97%
rename from pkgs/itcl4.0.4/tclconfig/tcl.m4
rename to pkgs/itcl4.0.5/tclconfig/tcl.m4
index f679256..203a05d 100644 (file)
@@ -13,12 +13,13 @@ 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.9"
+dnl TEA_VERSION="3.10"
 
 # Possible values for key variables defined:
 #
 # TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
 # TEA_PLATFORM        - windows unix
+# TEA_TK_EXTENSION    - True if this is a Tk extension
 #
 
 #------------------------------------------------------------------------
@@ -576,7 +577,15 @@ AC_DEFUN([TEA_PROG_TCLSH], [
     if test -f "${TCL_BIN_DIR}/Makefile" ; then
         # tclConfig.sh is in Tcl build directory
         if test "${TEA_PLATFORM}" = "windows"; then
+          if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" ; then
             TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}"
+          fi
         else
             TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
         fi
@@ -626,7 +635,15 @@ AC_DEFUN([TEA_PROG_WISH], [
     if test -f "${TK_BIN_DIR}/Makefile" ; then
         # tkConfig.sh is in Tk build directory
         if test "${TEA_PLATFORM}" = "windows"; then
+          if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" ; then
             WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}s${EXEEXT}" ; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}$s{EXEEXT}"
+          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}" ; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}"
+          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}" ; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}"
+          fi
         else
             WISH_PROG="${TK_BIN_DIR}/wish"
         fi
@@ -664,6 +681,7 @@ AC_DEFUN([TEA_PROG_WISH], [
 #
 #      Adds the following arguments to configure:
 #              --enable-shared=yes|no
+#              --enable-stubs=yes|no
 #
 #      Defines the following vars:
 #              STATIC_BUILD    Used for building import/export libraries
@@ -671,31 +689,63 @@ AC_DEFUN([TEA_PROG_WISH], [
 #
 #      Sets the following vars:
 #              SHARED_BUILD    Value of 1 or 0
+#               STUBS_BUILD     Value if 1 or 0
+#               USE_TCL_STUBS   Value true: if SHARED_BUILD or --enable-stubs
+#               USE_TCLOO_STUBS Value true: if SHARED_BUILD or --enable-stubs
+#               USE_TK_STUBS    Value true: if SHARED_BUILD or --enable-stubs
+#                                AND TEA_WINDOWING_SYSTEM != ""
 #------------------------------------------------------------------------
-
 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])
+       [shared_ok=$enableval], [shared_ok=yes])
 
     if test "${enable_shared+set}" = set; then
        enableval="$enable_shared"
-       tcl_ok=$enableval
+       shared_ok=$enableval
     else
-       tcl_ok=yes
+       shared_ok=yes
+    fi
+
+    AC_ARG_ENABLE(stubs,
+       AC_HELP_STRING([--enable-stubs],
+           [build and link with stub libraries. Always true for shared builds (default: on)]),
+       [stubs_ok=$enableval], [stubs_ok=yes])
+
+    if test "${enable_stubs+set}" = set; then
+       enableval="$enable_stubs"
+       stubs_ok=$enableval
+    else
+       stubs_ok=yes
     fi
 
-    if test "$tcl_ok" = "yes" ; then
+    # Stubs are always enabled for shared builds
+    if test "$shared_ok" = "yes" ; then
        AC_MSG_RESULT([shared])
        SHARED_BUILD=1
+        STUBS_BUILD=1
     else
        AC_MSG_RESULT([static])
        SHARED_BUILD=0
-       AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+       AC_DEFINE(STATIC_BUILD, 1, [This a static build])
+        if test "$stubs_ok" = "yes" ; then
+          STUBS_BUILD=1
+        else
+          STUBS_BUILD=0
+        fi
+    fi
+    if test "${STUBS_BUILD}" = "1" ; then
+      AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
+      AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO stubs])
+      if test "${TEA_WINDOWINGSYSTEM}" != ""; then
+        AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+      fi
     fi
+
     AC_SUBST(SHARED_BUILD)
+    AC_SUBST(STUBS_BUILD)
 ])
 
 #------------------------------------------------------------------------
@@ -2861,7 +2911,7 @@ AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
 AC_DEFUN([TEA_INIT], [
     # TEA extensions pass this us the version of TEA they think they
     # are compatible with.
-    TEA_VERSION="3.9"
+    TEA_VERSION="3.10"
 
     AC_MSG_CHECKING([for correct TEA configuration])
     if test x"${PACKAGE_NAME}" = x ; then
similarity index 97%
rename from pkgs/itcl4.0.4/tests/typeclass.test
rename to pkgs/itcl4.0.5/tests/typeclass.test
index 6ff667e..f1ae2e3 100644 (file)
@@ -269,7 +269,7 @@ test typeclass-rename-1.1 {mymethod uses name of instance name variable} -body {
     fido mymethod
 } -cleanup {
     dog destroy
-} -match glob -result {{::itcl::builtin::callinstance ItclInst*} {::itcl::builtin::callinstance ItclInst* {A B}} {::itcl::builtin::callinstance ItclInst* A B}}
+} -match glob -result {{::itcl::builtin::callinstance *} {::itcl::builtin::callinstance * {A B}} {::itcl::builtin::callinstance * A B}}
 
 
 test typeclass-rename-1.2 {instances can be renamed} -body {
@@ -287,7 +287,7 @@ test typeclass-rename-1.2 {instances can be renamed} -body {
     concat $a $b
 } -cleanup {
     dog destroy
-} -match glob -result {{::itcl::builtin::callinstance ItclInst*} ::itcl::internal::variables::*::dog fido ::fido {::itcl::builtin::callinstance ItclInst*} ::itcl::internal::variables::*::dog fido ::spot}
+} -match glob -result {{::itcl::builtin::callinstance *} ::itcl::internal::variables::*::dog fido ::fido {::itcl::builtin::callinstance *} ::itcl::internal::variables::*::dog fido ::spot}
 
 test rename-1.3 {rename to "" deletes an instance} -body {
     type dog { }
similarity index 85%
rename from pkgs/sqlite3.11.0/compat/sqlite3/shell.c
rename to pkgs/sqlite3.13.0/compat/sqlite3/shell.c
index c69cd00..3f96804 100644 (file)
@@ -90,7 +90,7 @@
 
 #else
 
-# define shell_read_history(X) 
+# define shell_read_history(X)
 # define shell_write_history(X)
 # define shell_stifle_history(X)
 
 #define IsDigit(X)  isdigit((unsigned char)X)
 #define ToLower(X)  (char)tolower((unsigned char)X)
 
+#if defined(_WIN32) || defined(WIN32)
+#include <windows.h>
+
+/* string conversion routines only needed on Win32 */
+extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
+extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
+extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
+#endif
+
 /* On Windows, we normally run with output mode of TEXT so that \n characters
 ** are automatically translated into \r\n.  However, this behavior needs
 ** to be disabled in some cases (ex: when generating CSV output and when
 ** routines take care of that.
 */
 #if defined(_WIN32) || defined(WIN32)
-static void setBinaryMode(FILE *out){
-  fflush(out);
-  _setmode(_fileno(out), _O_BINARY);
+static void setBinaryMode(FILE *file, int isOutput){
+  if( isOutput ) fflush(file);
+  _setmode(_fileno(file), _O_BINARY);
 }
-static void setTextMode(FILE *out){
-  fflush(out);
-  _setmode(_fileno(out), _O_TEXT);
+static void setTextMode(FILE *file, int isOutput){
+  if( isOutput ) fflush(file);
+  _setmode(_fileno(file), _O_TEXT);
 }
 #else
-# define setBinaryMode(X)
-# define setTextMode(X)
+# define setBinaryMode(X,Y)
+# define setTextMode(X,Y)
 #endif
 
 
@@ -204,7 +213,7 @@ static void beginTimer(void){
 
 /* Return the difference of two time_structs in seconds */
 static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
-  return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + 
+  return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
          (double)(pEnd->tv_sec - pStart->tv_sec);
 }
 
@@ -229,8 +238,6 @@ static void endTimer(void){
 
 #elif (defined(_WIN32) || defined(WIN32))
 
-#include <windows.h>
-
 /* Saved resource information for the beginning of an operation */
 static HANDLE hProcess;
 static FILETIME ftKernelBegin;
@@ -276,7 +283,7 @@ static void endTimer(void){
 #define HAS_TIMER 1
 
 #else
-#define BEGIN_TIMER 
+#define BEGIN_TIMER
 #define END_TIMER
 #define HAS_TIMER 0
 #endif
@@ -331,6 +338,38 @@ static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
 static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
 
 /*
+** Render output like fprintf().  Except, if the output is going to the
+** console and if this is running on a Windows machine, translate the
+** output from UTF-8 into MBCS.
+*/
+#if defined(_WIN32) || defined(WIN32)
+void utf8_printf(FILE *out, const char *zFormat, ...){
+  va_list ap;
+  va_start(ap, zFormat);
+  if( stdout_is_console && (out==stdout || out==stderr) ){
+    char *z1 = sqlite3_vmprintf(zFormat, ap);
+    char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
+    sqlite3_free(z1);
+    fputs(z2, out);
+    sqlite3_free(z2);
+  }else{
+    vfprintf(out, zFormat, ap);
+  }
+  va_end(ap);
+}
+#elif !defined(utf8_printf)
+# define utf8_printf fprintf
+#endif
+
+/*
+** Render output like fprintf().  This should not be used on anything that
+** includes string formatting (e.g. "%s").
+*/
+#if !defined(raw_printf)
+# define raw_printf fprintf
+#endif
+
+/*
 ** Write I/O traces to the following stream.
 */
 #ifdef SQLITE_ENABLE_IOTRACE
@@ -351,7 +390,7 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
   va_start(ap, zFormat);
   z = sqlite3_vmprintf(zFormat, ap);
   va_end(ap);
-  fprintf(iotrace, "%s", z);
+  utf8_printf(iotrace, "%s", z);
   sqlite3_free(z);
 }
 #endif
@@ -385,8 +424,8 @@ static int isNumber(const char *z, int *realnum){
 }
 
 /*
-** A global char* and an SQL function to access its current value 
-** from within an SQL statement. This program used to use the 
+** A global char* and an SQL function to access its current value
+** from within an SQL statement. This program used to use the
 ** sqlite_exec_printf() API to substitue a string into an SQL statement.
 ** The correct way to do this with sqlite3 is to use the bind API, but
 ** since the shell is built around the callback paradigm it would be a lot
@@ -452,11 +491,10 @@ static char *local_getline(char *zLine, FILE *in){
     }
   }
 #if defined(_WIN32) || defined(WIN32)
-  /* For interactive input on Windows systems, translate the 
+  /* For interactive input on Windows systems, translate the
   ** multi-byte characterset characters into UTF-8. */
   if( stdin_is_interactive ){
-    extern char *sqlite3_win32_mbcs_to_utf8(const char*);
-    char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine);
+    char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
     if( zTrans ){
       int nTrans = strlen30(zTrans)+1;
       if( nTrans>nLine ){
@@ -508,41 +546,21 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
   return zResult;
 }
 
+#if defined(SQLITE_ENABLE_SESSION)
 /*
-** Render output like fprintf().  Except, if the output is going to the
-** console and if this is running on a Windows machine, translate the
-** output from UTF-8 into MBCS.
-*/
-#if defined(_WIN32) || defined(WIN32)
-void utf8_printf(FILE *out, const char *zFormat, ...){
-  va_list ap;
-  va_start(ap, zFormat);
-  if( stdout_is_console && (out==stdout || out==stderr) ){
-    extern char *sqlite3_win32_utf8_to_mbcs(const char*);
-    char *z1 = sqlite3_vmprintf(zFormat, ap);
-    char *z2 = sqlite3_win32_utf8_to_mbcs(z1);
-    sqlite3_free(z1);
-    fputs(z2, out);
-    sqlite3_free(z2);
-  }else{
-    vfprintf(out, zFormat, ap);
-  }
-  va_end(ap);
-}
-#elif !defined(utf8_printf)
-# define utf8_printf fprintf
-#endif
-
-/*
-** Render output like fprintf().  This should not be used on anything that
-** includes string formatting (e.g. "%s").
+** State information for a single open session
 */
-#if !defined(raw_printf)
-# define raw_printf fprintf
+typedef struct OpenSession OpenSession;
+struct OpenSession {
+  char *zName;             /* Symbolic name for this session */
+  int nFilter;             /* Number of xFilter rejection GLOB patterns */
+  char **azFilter;         /* Array of xFilter rejection GLOB patterns */
+  sqlite3_session *p;      /* The open session */
+};
 #endif
 
 /*
-** Shell output mode information from before ".explain on", 
+** Shell output mode information from before ".explain on",
 ** saved so that it can be restored by ".explain off"
 */
 typedef struct SavedModeInfo SavedModeInfo;
@@ -594,6 +612,10 @@ struct ShellState {
   int *aiIndent;         /* Array of indents used in MODE_Explain */
   int nIndent;           /* Size of array aiIndent[] */
   int iIndent;           /* Index of current op in aiIndent[] */
+#if defined(SQLITE_ENABLE_SESSION)
+  int nSession;             /* Number of active sessions */
+  OpenSession aSession[4];  /* Array of sessions.  [0] is in focus. */
+#endif
 };
 
 /*
@@ -616,6 +638,7 @@ struct ShellState {
 #define MODE_Csv      7  /* Quote strings, numbers are plain */
 #define MODE_Explain  8  /* Like MODE_Column, but do not truncate data */
 #define MODE_Ascii    9  /* Use ASCII unit and record separators (0x1F/0x1E) */
+#define MODE_Pretty  10  /* Pretty-print schemas */
 
 static const char *const modeDescr[] = {
   "line",
@@ -628,6 +651,7 @@ static const char *const modeDescr[] = {
   "csv",
   "explain",
   "ascii",
+  "prettyprint",
 };
 
 /*
@@ -675,7 +699,7 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
 static void output_quoted_string(FILE *out, const char *z){
   int i;
   int nSingle = 0;
-  setBinaryMode(out);
+  setBinaryMode(out, 1);
   for(i=0; z[i]; i++){
     if( z[i]=='\'' ) nSingle++;
   }
@@ -698,7 +722,7 @@ static void output_quoted_string(FILE *out, const char *z){
     }
     raw_printf(out,"'");
   }
-  setTextMode(out);
+  setTextMode(out, 1);
 }
 
 /*
@@ -740,11 +764,11 @@ static void output_html_string(FILE *out, const char *z){
   int i;
   if( z==0 ) z = "";
   while( *z ){
-    for(i=0;   z[i] 
-            && z[i]!='<' 
-            && z[i]!='&' 
-            && z[i]!='>' 
-            && z[i]!='\"' 
+    for(i=0;   z[i]
+            && z[i]!='<'
+            && z[i]!='&'
+            && z[i]!='>'
+            && z[i]!='\"'
             && z[i]!='\'';
         i++){}
     if( i>0 ){
@@ -772,22 +796,22 @@ static void output_html_string(FILE *out, const char *z){
 ** array, then the string must be quoted for CSV.
 */
 static const char needCsvQuote[] = {
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1, 
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
-  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
 };
 
 /*
@@ -804,8 +828,8 @@ static void output_csv(ShellState *p, const char *z, int bSep){
     int i;
     int nSep = strlen30(p->colSeparator);
     for(i=0; z[i]; i++){
-      if( needCsvQuote[((unsigned char*)z)[i]] 
-         || (z[i]==p->colSeparator[0] && 
+      if( needCsvQuote[((unsigned char*)z)[i]]
+         || (z[i]==p->colSeparator[0] &&
              (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
         i = 0;
         break;
@@ -856,6 +880,52 @@ BOOL WINAPI CtrlHandler(DWORD dwType){
 #endif
 
 /*
+** When the ".auth ON" is set, the following authorizer callback is
+** invoked.  It always returns SQLITE_OK.
+*/
+static int shellAuth(
+  void *pClientData,
+  int op,
+  const char *zA1,
+  const char *zA2,
+  const char *zA3,
+  const char *zA4
+){
+  ShellState *p = (ShellState*)pClientData;
+  static const char *const azAction[] = { 0,
+     "CREATE_INDEX",         "CREATE_TABLE",         "CREATE_TEMP_INDEX",
+     "CREATE_TEMP_TABLE",    "CREATE_TEMP_TRIGGER",  "CREATE_TEMP_VIEW",
+     "CREATE_TRIGGER",       "CREATE_VIEW",          "DELETE",
+     "DROP_INDEX",           "DROP_TABLE",           "DROP_TEMP_INDEX",
+     "DROP_TEMP_TABLE",      "DROP_TEMP_TRIGGER",    "DROP_TEMP_VIEW",
+     "DROP_TRIGGER",         "DROP_VIEW",            "INSERT",
+     "PRAGMA",               "READ",                 "SELECT",
+     "TRANSACTION",          "UPDATE",               "ATTACH",
+     "DETACH",               "ALTER_TABLE",          "REINDEX",
+     "ANALYZE",              "CREATE_VTABLE",        "DROP_VTABLE",
+     "FUNCTION",             "SAVEPOINT",            "RECURSIVE"
+  };
+  int i;
+  const char *az[4];
+  az[0] = zA1;
+  az[1] = zA2;
+  az[2] = zA3;
+  az[3] = zA4;
+  raw_printf(p->out, "authorizer: %s", azAction[op]);
+  for(i=0; i<4; i++){
+    raw_printf(p->out, " ");
+    if( az[i] ){
+      output_c_string(p->out, az[i]);
+    }else{
+      raw_printf(p->out, "NULL");
+    }
+  }
+  raw_printf(p->out, "\n");
+  return SQLITE_OK;
+}
+  
+
+/*
 ** This is the callback routine that the shell
 ** invokes for each row of a query result.
 */
@@ -971,7 +1041,70 @@ static int shell_callback(
       }
       break;
     }
-    case MODE_Semi:
+    case MODE_Semi: {   /* .schema and .fullschema output */
+      utf8_printf(p->out, "%s;\n", azArg[0]);
+      break;
+    }
+    case MODE_Pretty: {  /* .schema and .fullschema with --indent */
+      char *z;
+      int j;
+      int nParen = 0;
+      char cEnd = 0;
+      char c;
+      int nLine = 0;
+      assert( nArg==1 );
+      if( azArg[0]==0 ) break;
+      if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
+       || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
+      ){
+        utf8_printf(p->out, "%s;\n", azArg[0]);
+        break;
+      }
+      z = sqlite3_mprintf("%s", azArg[0]);
+      j = 0;
+      for(i=0; IsSpace(z[i]); i++){}
+      for(; (c = z[i])!=0; i++){
+        if( IsSpace(c) ){
+          if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
+        }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
+          j--;
+        }
+        z[j++] = c;
+      }
+      while( j>0 && IsSpace(z[j-1]) ){ j--; }
+      z[j] = 0;
+      if( strlen30(z)>=79 ){
+        for(i=j=0; (c = z[i])!=0; i++){
+          if( c==cEnd ){
+            cEnd = 0;
+          }else if( c=='"' || c=='\'' || c=='`' ){
+            cEnd = c;
+          }else if( c=='[' ){
+            cEnd = ']';
+          }else if( c=='(' ){
+            nParen++;
+          }else if( c==')' ){
+            nParen--;
+            if( nLine>0 && nParen==0 && j>0 ){
+              utf8_printf(p->out, "%.*s\n", j, z);
+              j = 0;
+            }
+          }
+          z[j++] = c;
+          if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
+            if( c=='\n' ) j--;
+            utf8_printf(p->out, "%.*s\n  ", j, z);
+            j = 0;
+            nLine++;
+            while( IsSpace(z[i+1]) ){ i++; }
+          }
+        }
+        z[j] = 0;
+      }
+      utf8_printf(p->out, "%s;\n", z);
+      sqlite3_free(z);
+      break;
+    }
     case MODE_List: {
       if( p->cnt++==0 && p->showHeader ){
         for(i=0; i<nArg; i++){
@@ -986,8 +1119,6 @@ static int shell_callback(
         utf8_printf(p->out, "%s", z);
         if( i<nArg-1 ){
           utf8_printf(p->out, "%s", p->colSeparator);
-        }else if( p->cMode==MODE_Semi ){
-          utf8_printf(p->out, ";%s", p->rowSeparator);
         }else{
           utf8_printf(p->out, "%s", p->rowSeparator);
         }
@@ -1031,7 +1162,7 @@ static int shell_callback(
       break;
     }
     case MODE_Csv: {
-      setBinaryMode(p->out);
+      setBinaryMode(p->out, 1);
       if( p->cnt++==0 && p->showHeader ){
         for(i=0; i<nArg; i++){
           output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
@@ -1044,7 +1175,7 @@ static int shell_callback(
         }
         utf8_printf(p->out, "%s", p->rowSeparator);
       }
-      setTextMode(p->out);
+      setTextMode(p->out, 1);
       break;
     }
     case MODE_Insert: {
@@ -1157,7 +1288,7 @@ static void set_table_name(ShellState *p, const char *zName){
 ** added to zIn, and the result returned in memory obtained from malloc().
 ** zIn, if it was not NULL, is freed.
 **
-** If the third argument, quote, is not '\0', then it is used as a 
+** If the third argument, quote, is not '\0', then it is used as a
 ** quote character for zAppend.
 */
 static char *appendText(char *zIn, char const *zAppend, char quote){
@@ -1204,7 +1335,7 @@ static char *appendText(char *zIn, char const *zAppend, char quote){
 ** semicolon terminator to the end of that line.
 **
 ** If the number of columns is 1 and that column contains text "--"
-** then write the semicolon on a separate line.  That way, if a 
+** then write the semicolon on a separate line.  That way, if a
 ** "--" comment occurs at the end of the statement, the comment
 ** won't consume the semicolon terminator.
 */
@@ -1234,7 +1365,7 @@ static int run_table_dump_query(
     }
     z = (const char*)sqlite3_column_text(pSelect, 0);
     utf8_printf(p->out, "%s", z);
-    for(i=1; i<nResult; i++){ 
+    for(i=1; i<nResult; i++){
       utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
     }
     if( z==0 ) z = "";
@@ -1243,7 +1374,7 @@ static int run_table_dump_query(
       raw_printf(p->out, "\n;\n");
     }else{
       raw_printf(p->out, ";\n");
-    }    
+    }
     rc = sqlite3_step(pSelect);
   }
   rc = sqlite3_finalize(pSelect);
@@ -1269,6 +1400,43 @@ static char *save_err_msg(
   return zErrMsg;
 }
 
+#ifdef __linux__
+/*
+** Attempt to display I/O stats on Linux using /proc/PID/io
+*/
+static void displayLinuxIoStats(FILE *out){
+  FILE *in;
+  char z[200];
+  sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
+  in = fopen(z, "rb");
+  if( in==0 ) return;
+  while( fgets(z, sizeof(z), in)!=0 ){
+    static const struct {
+      const char *zPattern;
+      const char *zDesc;
+    } aTrans[] = {
+      { "rchar: ",                  "Bytes received by read():" },
+      { "wchar: ",                  "Bytes sent to write():"    },
+      { "syscr: ",                  "Read() system calls:"      },
+      { "syscw: ",                  "Write() system calls:"     },
+      { "read_bytes: ",             "Bytes read from storage:"  },
+      { "write_bytes: ",            "Bytes written to storage:" },
+      { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
+    };
+    int i;
+    for(i=0; i<ArraySize(aTrans); i++){
+      int n = (int)strlen(aTrans[i].zPattern);
+      if( strncmp(aTrans[i].zPattern, z, n)==0 ){
+        raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
+        break;
+      }
+    }
+  }
+  fclose(in);
+}
+#endif
+
+
 /*
 ** Display memory stats.
 */
@@ -1281,7 +1449,7 @@ static int display_stats(
   int iHiwtr;
 
   if( pArg && pArg->out ){
-    
+
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
     raw_printf(pArg->out,
@@ -1365,18 +1533,18 @@ static int display_stats(
     raw_printf(pArg->out, "Page cache hits:                     %d\n", iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
-    raw_printf(pArg->out, "Page cache misses:                   %d\n", iCur); 
+    raw_printf(pArg->out, "Page cache misses:                   %d\n", iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
-    raw_printf(pArg->out, "Page cache writes:                   %d\n", iCur); 
+    raw_printf(pArg->out, "Page cache writes:                   %d\n", iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
     raw_printf(pArg->out, "Schema Heap Usage:                   %d bytes\n",
-            iCur); 
+            iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
     raw_printf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n",
-            iCur); 
+            iCur);
   }
 
   if( pArg && pArg->out && db && pArg->pStmt ){
@@ -1391,6 +1559,10 @@ static int display_stats(
     raw_printf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
   }
 
+#ifdef __linux__
+  displayLinuxIoStats(pArg->out);
+#endif
+
   /* Do not remove this machine readable comment: extra-stats-output-here */
 
   return 0;
@@ -1434,7 +1606,7 @@ static void display_scanstats(
       sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
       utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
       rEstLoop *= rEst;
-      raw_printf(pArg->out, 
+      raw_printf(pArg->out,
           "         nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
           nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
       );
@@ -1461,7 +1633,7 @@ static int str_in_array(const char *zStr, const char *const *azArray){
 /*
 ** If compiled statement pSql appears to be an EXPLAIN statement, allocate
 ** and populate the ShellState.aiIndent[] array with the number of
-** spaces each opcode should be indented before it is output. 
+** spaces each opcode should be indented before it is output.
 **
 ** The indenting rules are:
 **
@@ -1546,7 +1718,7 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
     if( str_in_array(zOp, azGoto) && p2op<p->nIndent
      && (abYield[p2op] || sqlite3_column_int(pSql, 2))
     ){
-      for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
+      for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
     }
   }
 
@@ -1566,12 +1738,110 @@ static void explain_data_delete(ShellState *p){
 }
 
 /*
-** Execute a statement or set of statements.  Print 
-** any result rows/columns depending on the current mode 
+** Disable and restore .wheretrace and .selecttrace settings.
+*/
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
+extern int sqlite3SelectTrace;
+static int savedSelectTrace;
+#endif
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
+extern int sqlite3WhereTrace;
+static int savedWhereTrace;
+#endif
+static void disable_debug_trace_modes(void){
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
+  savedSelectTrace = sqlite3SelectTrace;
+  sqlite3SelectTrace = 0;
+#endif
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
+  savedWhereTrace = sqlite3WhereTrace;
+  sqlite3WhereTrace = 0;
+#endif
+}
+static void restore_debug_trace_modes(void){
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
+  sqlite3SelectTrace = savedSelectTrace;
+#endif
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
+  sqlite3WhereTrace = savedWhereTrace;
+#endif
+}
+
+/*
+** Run a prepared statement
+*/
+static void exec_prepared_stmt(
+  ShellState *pArg,                                /* Pointer to ShellState */
+  sqlite3_stmt *pStmt,                             /* Statment to run */
+  int (*xCallback)(void*,int,char**,char**,int*)   /* Callback function */
+){
+  int rc;
+
+  /* perform the first step.  this will tell us if we
+  ** have a result set or not and how wide it is.
+  */
+  rc = sqlite3_step(pStmt);
+  /* if we have a result set... */
+  if( SQLITE_ROW == rc ){
+    /* if we have a callback... */
+    if( xCallback ){
+      /* allocate space for col name ptr, value ptr, and type */
+      int nCol = sqlite3_column_count(pStmt);
+      void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
+      if( !pData ){
+        rc = SQLITE_NOMEM;
+      }else{
+        char **azCols = (char **)pData;      /* Names of result columns */
+        char **azVals = &azCols[nCol];       /* Results */
+        int *aiTypes = (int *)&azVals[nCol]; /* Result types */
+        int i, x;
+        assert(sizeof(int) <= sizeof(char *));
+        /* save off ptrs to column names */
+        for(i=0; i<nCol; i++){
+          azCols[i] = (char *)sqlite3_column_name(pStmt, i);
+        }
+        do{
+          /* extract the data and data types */
+          for(i=0; i<nCol; i++){
+            aiTypes[i] = x = sqlite3_column_type(pStmt, i);
+            if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
+              azVals[i] = "";
+            }else{
+              azVals[i] = (char*)sqlite3_column_text(pStmt, i);
+            }
+            if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
+              rc = SQLITE_NOMEM;
+              break; /* from for */
+            }
+          } /* end for */
+
+          /* if data and types extracted successfully... */
+          if( SQLITE_ROW == rc ){
+            /* call the supplied callback with the result row data */
+            if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
+              rc = SQLITE_ABORT;
+            }else{
+              rc = sqlite3_step(pStmt);
+            }
+          }
+        } while( SQLITE_ROW == rc );
+        sqlite3_free(pData);
+      }
+    }else{
+      do{
+        rc = sqlite3_step(pStmt);
+      } while( rc == SQLITE_ROW );
+    }
+  }
+}
+
+/*
+** Execute a statement or set of statements.  Print
+** any result rows/columns depending on the current mode
 ** set via the supplied callback.
 **
-** This is very similar to SQLite's built-in sqlite3_exec() 
-** function except it takes a slightly different callback 
+** This is very similar to SQLite's built-in sqlite3_exec()
+** function except it takes a slightly different callback
 ** and callback data argument.
 */
 static int shell_exec(
@@ -1592,6 +1862,7 @@ static int shell_exec(
   }
 
   while( zSql[0] && (SQLITE_OK == rc) ){
+    static const char *zStmtSql;
     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
     if( SQLITE_OK != rc ){
       if( pzErrMsg ){
@@ -1604,6 +1875,8 @@ static int shell_exec(
         while( IsSpace(zSql[0]) ) zSql++;
         continue;
       }
+      zStmtSql = sqlite3_sql(pStmt);
+      while( IsSpace(zStmtSql[0]) ) zStmtSql++;
 
       /* save off the prepared statment handle and reset row count */
       if( pArg ){
@@ -1613,15 +1886,15 @@ static int shell_exec(
 
       /* echo the sql statement if echo on */
       if( pArg && pArg->echoOn ){
-        const char *zStmtSql = sqlite3_sql(pStmt);
         utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
       }
 
       /* Show the EXPLAIN QUERY PLAN if .eqp is on */
-      if( pArg && pArg->autoEQP ){
+      if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
         sqlite3_stmt *pExplain;
-        char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
-                                     sqlite3_sql(pStmt));
+        char *zEQP;
+        disable_debug_trace_modes();
+        zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
         rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
         if( rc==SQLITE_OK ){
           while( sqlite3_step(pExplain)==SQLITE_ROW ){
@@ -1633,17 +1906,31 @@ static int shell_exec(
         }
         sqlite3_finalize(pExplain);
         sqlite3_free(zEQP);
+        if( pArg->autoEQP>=2 ){
+          /* Also do an EXPLAIN for ".eqp full" mode */
+          zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
+          rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
+          if( rc==SQLITE_OK ){
+            pArg->cMode = MODE_Explain;
+            explain_data_prepare(pArg, pExplain);
+            exec_prepared_stmt(pArg, pExplain, xCallback);
+            explain_data_delete(pArg);
+          }
+          sqlite3_finalize(pExplain);
+          sqlite3_free(zEQP);
+        }
+        restore_debug_trace_modes();
       }
 
       if( pArg ){
         pArg->cMode = pArg->mode;
         if( pArg->autoExplain
          && sqlite3_column_count(pStmt)==8
-         && sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
+         && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
         ){
           pArg->cMode = MODE_Explain;
         }
-      
+
         /* If the shell is currently in ".explain" mode, gather the extra
         ** data required to add indents to the output.*/
         if( pArg->cMode==MODE_Explain ){
@@ -1651,63 +1938,7 @@ static int shell_exec(
         }
       }
 
-      /* perform the first step.  this will tell us if we
-      ** have a result set or not and how wide it is.
-      */
-      rc = sqlite3_step(pStmt);
-      /* if we have a result set... */
-      if( SQLITE_ROW == rc ){
-        /* if we have a callback... */
-        if( xCallback ){
-          /* allocate space for col name ptr, value ptr, and type */
-          int nCol = sqlite3_column_count(pStmt);
-          void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
-          if( !pData ){
-            rc = SQLITE_NOMEM;
-          }else{
-            char **azCols = (char **)pData;      /* Names of result columns */
-            char **azVals = &azCols[nCol];       /* Results */
-            int *aiTypes = (int *)&azVals[nCol]; /* Result types */
-            int i, x;
-            assert(sizeof(int) <= sizeof(char *)); 
-            /* save off ptrs to column names */
-            for(i=0; i<nCol; i++){
-              azCols[i] = (char *)sqlite3_column_name(pStmt, i);
-            }
-            do{
-              /* extract the data and data types */
-              for(i=0; i<nCol; i++){
-                aiTypes[i] = x = sqlite3_column_type(pStmt, i);
-                if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
-                  azVals[i] = "";
-                }else{
-                  azVals[i] = (char*)sqlite3_column_text(pStmt, i);
-                }
-                if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
-                  rc = SQLITE_NOMEM;
-                  break; /* from for */
-                }
-              } /* end for */
-
-              /* if data and types extracted successfully... */
-              if( SQLITE_ROW == rc ){ 
-                /* call the supplied callback with the result row data */
-                if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
-                  rc = SQLITE_ABORT;
-                }else{
-                  rc = sqlite3_step(pStmt);
-                }
-              }
-            } while( SQLITE_ROW == rc );
-            sqlite3_free(pData);
-          }
-        }else{
-          do{
-            rc = sqlite3_step(pStmt);
-          } while( rc == SQLITE_ROW );
-        }
-      }
-
+      exec_prepared_stmt(pArg, pStmt, xCallback);
       explain_data_delete(pArg);
 
       /* print usage stats if stats on */
@@ -1720,7 +1951,7 @@ static int shell_exec(
         display_scanstats(db, pArg);
       }
 
-      /* Finalize the statement just executed. If this fails, save a 
+      /* Finalize the statement just executed. If this fails, save a
       ** copy of the error message. Otherwise, set zSql to point to the
       ** next statement to execute. */
       rc2 = sqlite3_finalize(pStmt);
@@ -1762,7 +1993,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
   zTable = azArg[0];
   zType = azArg[1];
   zSql = azArg[2];
-  
+
   if( strcmp(zTable, "sqlite_sequence")==0 ){
     zPrepStmt = "DELETE FROM sqlite_sequence;\n";
   }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
@@ -1792,7 +2023,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
     char *zTableInfo = 0;
     char *zTmp = 0;
     int nRow = 0;
-   
+
     zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
     zTableInfo = appendText(zTableInfo, zTable, '"');
     zTableInfo = appendText(zTableInfo, ");", 0);
@@ -1851,7 +2082,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
 ** "ORDER BY rowid DESC" to the end.
 */
 static int run_schema_dump_query(
-  ShellState *p, 
+  ShellState *p,
   const char *zQuery
 ){
   int rc;
@@ -1885,6 +2116,7 @@ static int run_schema_dump_query(
 ** Text of a help message
 */
 static char zHelp[] =
+  ".auth ON|OFF           Show authorizer callbacks\n"
   ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
   ".bail on|off           Stop after hitting an error.  Default OFF\n"
   ".binary on|off         Turn binary output on or off.  Default OFF\n"
@@ -1896,10 +2128,10 @@ static char zHelp[] =
   "                         If TABLE specified, only dump tables matching\n"
   "                         LIKE pattern TABLE.\n"
   ".echo on|off           Turn command echo on or off\n"
-  ".eqp on|off            Enable or disable automatic EXPLAIN QUERY PLAN\n"
+  ".eqp on|off|full       Enable or disable automatic EXPLAIN QUERY PLAN\n"
   ".exit                  Exit this program\n"
   ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
-  ".fullschema            Show schema and the content of sqlite_stat tables\n"
+  ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
   ".headers on|off        Turn display of headers on or off\n"
   ".help                  Show this message\n"
   ".import FILE TABLE     Import data from FILE into TABLE\n"
@@ -1935,14 +2167,16 @@ static char zHelp[] =
   ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
   ".save FILE             Write in-memory database into FILE\n"
   ".scanstats on|off      Turn sqlite3_stmt_scanstatus() metrics on or off\n"
-  ".schema ?TABLE?        Show the CREATE statements\n"
-  "                         If TABLE specified, only show tables matching\n"
-  "                         LIKE pattern TABLE.\n"
+  ".schema ?PATTERN?      Show the CREATE statements matching PATTERN\n"
+  "                          Add --indent for pretty-printing\n"
   ".separator COL ?ROW?   Change the column separator and optionally the row\n"
   "                         separator for both the output mode and .import\n"
+#if defined(SQLITE_ENABLE_SESSION)
+  ".session CMD ...       Create or control sessions\n"
+#endif
   ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
   ".show                  Show the current values for various settings\n"
-  ".stats on|off          Turn stats on or off\n"
+  ".stats ?on|off?        Show stats or turn stats on or off\n"
   ".system CMD ARGS...    Run CMD ARGS... in a system shell\n"
   ".tables ?TABLE?        List names of tables\n"
   "                         If TABLE specified, only list tables matching\n"
@@ -1957,6 +2191,30 @@ static char zHelp[] =
   "                         Negative values right-justify\n"
 ;
 
+#if defined(SQLITE_ENABLE_SESSION)
+/*
+** Print help information for the ".sessions" command
+*/
+void session_help(ShellState *p){
+  raw_printf(p->out,
+    ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
+    "If ?NAME? is omitted, the first defined session is used.\n"
+    "Subcommands:\n"
+    "   attach TABLE             Attach TABLE\n"
+    "   changeset FILE           Write a changeset into FILE\n"
+    "   close                    Close one session\n"
+    "   enable ?BOOLEAN?         Set or query the enable bit\n"
+    "   filter GLOB...           Reject tables matching GLOBs\n"
+    "   indirect ?BOOLEAN?       Mark or query the indirect status\n"
+    "   isempty                  Query whether the session is empty\n"
+    "   list                     List currently open session names\n"
+    "   open DB NAME             Open a new session on DB\n"
+    "   patchset FILE            Write a patchset into FILE\n"
+  );
+}
+#endif
+
+
 /* Forward reference */
 static int process_input(ShellState *p, FILE *in);
 /*
@@ -2022,6 +2280,53 @@ static void writefileFunc(
   sqlite3_result_int64(context, rc);
 }
 
+#if defined(SQLITE_ENABLE_SESSION)
+/*
+** Close a single OpenSession object and release all of its associated
+** resources.
+*/
+static void session_close(OpenSession *pSession){
+  int i;
+  sqlite3session_delete(pSession->p);
+  sqlite3_free(pSession->zName);
+  for(i=0; i<pSession->nFilter; i++){
+    sqlite3_free(pSession->azFilter[i]);
+  }
+  sqlite3_free(pSession->azFilter);
+  memset(pSession, 0, sizeof(OpenSession));
+}
+#endif
+
+/*
+** Close all OpenSession objects and release all associated resources.
+*/
+#if defined(SQLITE_ENABLE_SESSION)
+static void session_close_all(ShellState *p){
+  int i;
+  for(i=0; i<p->nSession; i++){
+    session_close(&p->aSession[i]);
+  }
+  p->nSession = 0;
+}
+#else
+# define session_close_all(X)
+#endif
+
+/*
+** Implementation of the xFilter function for an open session.  Omit
+** any tables named by ".session filter" but let all other table through.
+*/
+#if defined(SQLITE_ENABLE_SESSION)
+static int session_filter(void *pCtx, const char *zTab){
+  OpenSession *pSession = (OpenSession*)pCtx;
+  int i;
+  for(i=0; i<pSession->nFilter; i++){
+    if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
+  }
+  return 1;
+}
+#endif
+
 /*
 ** Make sure the database is open.  If it is not, then open it.  If
 ** the database fails to open, print an error message and exit.
@@ -2036,7 +2341,7 @@ static void open_db(ShellState *p, int keepAlive){
           shellstaticFunc, 0, 0);
     }
     if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
-      utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", 
+      utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
           p->zDbFilename, sqlite3_errmsg(p->db));
       if( keepAlive ) return;
       exit(1);
@@ -2172,7 +2477,7 @@ static sqlite3_int64 integerValue(const char *zArg){
 ** Interpret zArg as either an integer or a boolean value.  Return 1 or 0
 ** for TRUE and FALSE.  Return the integer value if appropriate.
 */
-static int booleanValue(char *zArg){
+static int booleanValue(const char *zArg){
   int i;
   if( zArg[0]=='0' && zArg[1]=='x' ){
     for(i=2; hexDigitValue(zArg[i])>=0; i++){}
@@ -2200,7 +2505,7 @@ static void output_file_close(FILE *f){
 
 /*
 ** Try to open an output file.   The names "stdout" and "stderr" are
-** recognized and do the right thing.  NULL is returned if the output 
+** recognized and do the right thing.  NULL is returned if the output
 ** filename is "off".
 */
 static FILE *output_file_open(const char *zFile){
@@ -2389,7 +2694,7 @@ static void tryToCloneData(
   sqlite3 *newDb,
   const char *zTable
 ){
-  sqlite3_stmt *pQuery = 0; 
+  sqlite3_stmt *pQuery = 0;
   sqlite3_stmt *pInsert = 0;
   char *zQuery = 0;
   char *zInsert = 0;
@@ -2693,9 +2998,9 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
     utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
     switch( ofst ){
       case 56: {
-        if( val==1 ) raw_printf(p->out, " (utf8)"); 
-        if( val==2 ) raw_printf(p->out, " (utf16le)"); 
-        if( val==3 ) raw_printf(p->out, " (utf16be)"); 
+        if( val==1 ) raw_printf(p->out, " (utf8)");
+        if( val==2 ) raw_printf(p->out, " (utf16le)");
+        if( val==3 ) raw_printf(p->out, " (utf16be)");
       }
     }
     raw_printf(p->out, "\n");
@@ -2735,6 +3040,17 @@ static int shellNomemError(void){
 }
 
 /*
+** Compare the string as a command-line option with either one or two
+** initial "-" characters.
+*/
+static int optionMatch(const char *zStr, const char *zOpt){
+  if( zStr[0]!='-' ) return 0;
+  zStr++;
+  if( zStr[0]=='-' ) zStr++;
+  return strcmp(zStr, zOpt)==0;
+}
+
+/*
 ** If an input line begins with "." then invoke this routine to
 ** process that line.
 **
@@ -2755,9 +3071,9 @@ static int do_meta_command(char *zLine, ShellState *p){
     if( zLine[h]=='\'' || zLine[h]=='"' ){
       int delim = zLine[h++];
       azArg[nArg++] = &zLine[h];
-      while( zLine[h] && zLine[h]!=delim ){ 
+      while( zLine[h] && zLine[h]!=delim ){
         if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
-        h++; 
+        h++;
       }
       if( zLine[h]==delim ){
         zLine[h++] = 0;
@@ -2776,6 +3092,21 @@ static int do_meta_command(char *zLine, ShellState *p){
   if( nArg==0 ) return 0; /* no tokens, no error */
   n = strlen30(azArg[0]);
   c = azArg[0][0];
+
+  if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
+    if( nArg!=2 ){
+      raw_printf(stderr, "Usage: .auth ON|OFF\n");
+      rc = 1;
+      goto meta_command_exit;
+    }
+    open_db(p, 0);
+    if( booleanValue(azArg[1]) ){
+      sqlite3_set_authorizer(p->db, shellAuth, p);
+    }else{
+      sqlite3_set_authorizer(p->db, 0, 0);
+    }
+  }else
+
   if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
    || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
   ){
@@ -2844,9 +3175,9 @@ static int do_meta_command(char *zLine, ShellState *p){
   if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
     if( nArg==2 ){
       if( booleanValue(azArg[1]) ){
-        setBinaryMode(p->out);
+        setBinaryMode(p->out, 1);
       }else{
-        setTextMode(p->out);
+        setTextMode(p->out, 1);
       }
     }else{
       raw_printf(stderr, "Usage: .binary on|off\n");
@@ -2918,11 +3249,11 @@ static int do_meta_command(char *zLine, ShellState *p){
     sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
     p->nErr = 0;
     if( nArg==1 ){
-      run_schema_dump_query(p, 
+      run_schema_dump_query(p,
         "SELECT name, type, sql FROM sqlite_master "
         "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
       );
-      run_schema_dump_query(p, 
+      run_schema_dump_query(p,
         "SELECT name, type, sql FROM sqlite_master "
         "WHERE name=='sqlite_sequence'"
       );
@@ -2967,11 +3298,15 @@ static int do_meta_command(char *zLine, ShellState *p){
 
   if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
     if( nArg==2 ){
-      p->autoEQP = booleanValue(azArg[1]);
+      if( strcmp(azArg[1],"full")==0 ){
+        p->autoEQP = 2;
+      }else{
+        p->autoEQP = booleanValue(azArg[1]);
+      }
     }else{
-      raw_printf(stderr, "Usage: .eqp on|off\n");
+      raw_printf(stderr, "Usage: .eqp on|off|full\n");
       rc = 1;
-    }   
+    }
   }else
 
   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
@@ -3005,15 +3340,19 @@ static int do_meta_command(char *zLine, ShellState *p){
     ShellState data;
     char *zErrMsg = 0;
     int doStats = 0;
+    memcpy(&data, p, sizeof(data));
+    data.showHeader = 0;
+    data.cMode = data.mode = MODE_Semi;
+    if( nArg==2 && optionMatch(azArg[1], "indent") ){
+      data.cMode = data.mode = MODE_Pretty;
+      nArg = 1;
+    }
     if( nArg!=1 ){
-      raw_printf(stderr, "Usage: .fullschema\n");
+      raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
       rc = 1;
       goto meta_command_exit;
     }
     open_db(p, 0);
-    memcpy(&data, p, sizeof(data));
-    data.showHeader = 0;
-    data.cMode = data.mode = MODE_Semi;
     rc = sqlite3_exec(p->db,
        "SELECT sql FROM"
        "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
@@ -3156,7 +3495,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
       char cSep = '(';
       while( xRead(&sCtx) ){
-        zCreate = sqlite3_mprintf("%z%c\n  \"%s\" TEXT", zCreate, cSep, sCtx.z);
+        zCreate = sqlite3_mprintf("%z%c\n  \"%w\" TEXT", zCreate, cSep, sCtx.z);
         cSep = ',';
         if( sCtx.cTerm!=sCtx.cColSep ) break;
       }
@@ -3353,7 +3692,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     open_db(p, 0);
     if( nArg==1 ){
       for(i=0; i<ArraySize(aLimit); i++){
-        printf("%20s %d\n", aLimit[i].zLimitName, 
+        printf("%20s %d\n", aLimit[i].zLimitName,
                sqlite3_limit(p->db, aLimit[i].limitCode, -1));
       }
     }else if( nArg>3 ){
@@ -3478,6 +3817,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     p->zDbFilename = zNewFilename;
     open_db(p, 1);
     if( p->db!=0 ){
+      session_close_all(p);
       sqlite3_close(savedDb);
       sqlite3_free(p->zFreeOnClose);
       p->zFreeOnClose = zNewFilename;
@@ -3647,7 +3987,12 @@ static int do_meta_command(char *zLine, ShellState *p){
     memcpy(&data, p, sizeof(data));
     data.showHeader = 0;
     data.cMode = data.mode = MODE_Semi;
-    if( nArg==2 ){
+    if( nArg>=2 && optionMatch(azArg[1], "indent") ){
+      data.cMode = data.mode = MODE_Pretty;
+      nArg--;
+      if( nArg==2 ) azArg[1] = azArg[2];
+    }
+    if( nArg==2 && azArg[1][0]!='-' ){
       int i;
       for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
       if( strcmp(azArg[1],"sqlite_master")==0 ){
@@ -3702,7 +4047,7 @@ static int do_meta_command(char *zLine, ShellState *p){
          callback, &data, &zErrMsg
       );
     }else{
-      raw_printf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
+      raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -3718,14 +4063,207 @@ static int do_meta_command(char *zLine, ShellState *p){
     }
   }else
 
-
 #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
   if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
-    extern int sqlite3SelectTrace;
     sqlite3SelectTrace = integerValue(azArg[1]);
   }else
 #endif
 
+#if defined(SQLITE_ENABLE_SESSION)
+  if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
+    OpenSession *pSession = &p->aSession[0];
+    char **azCmd = &azArg[1];
+    int iSes = 0;
+    int nCmd = nArg - 1;
+    int i;
+    if( nArg<=1 ) goto session_syntax_error;
+    open_db(p, 0);
+    if( nArg>=3 ){
+      for(iSes=0; iSes<p->nSession; iSes++){
+        if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
+      }
+      if( iSes<p->nSession ){
+        pSession = &p->aSession[iSes];
+        azCmd++;
+        nCmd--;
+      }else{
+        pSession = &p->aSession[0];
+        iSes = 0;
+      }
+    }
+
+    /* .session attach TABLE
+    ** Invoke the sqlite3session_attach() interface to attach a particular
+    ** table so that it is never filtered.
+    */
+    if( strcmp(azCmd[0],"attach")==0 ){
+      if( nCmd!=2 ) goto session_syntax_error;
+      if( pSession->p==0 ){
+        session_not_open:
+        raw_printf(stderr, "ERROR: No sessions are open\n");
+      }else{
+        rc = sqlite3session_attach(pSession->p, azCmd[1]);
+        if( rc ){
+          raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
+          rc = 0;
+        }
+      }
+    }else
+
+    /* .session changeset FILE
+    ** .session patchset FILE
+    ** Write a changeset or patchset into a file.  The file is overwritten.
+    */
+    if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
+      FILE *out = 0;
+      if( nCmd!=2 ) goto session_syntax_error;
+      if( pSession->p==0 ) goto session_not_open;
+      out = fopen(azCmd[1], "wb");
+      if( out==0 ){
+        utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
+      }else{
+        int szChng;
+        void *pChng;
+        if( azCmd[0][0]=='c' ){
+          rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
+        }else{
+          rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
+        }
+        if( rc ){
+          printf("Error: error code %d\n", rc);
+          rc = 0;
+        }
+        if( pChng
+          && fwrite(pChng, szChng, 1, out)!=1 ){
+          raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
+                  szChng);
+        }
+        sqlite3_free(pChng);
+        fclose(out);
+      }
+    }else
+
+    /* .session close
+    ** Close the identified session
+    */
+    if( strcmp(azCmd[0], "close")==0 ){
+      if( nCmd!=1 ) goto session_syntax_error;
+      if( p->nSession ){
+        session_close(pSession);
+        p->aSession[iSes] = p->aSession[--p->nSession];
+      }
+    }else
+
+    /* .session enable ?BOOLEAN?
+    ** Query or set the enable flag
+    */
+    if( strcmp(azCmd[0], "enable")==0 ){
+      int ii;
+      if( nCmd>2 ) goto session_syntax_error;
+      ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
+      if( p->nSession ){
+        ii = sqlite3session_enable(pSession->p, ii);
+        utf8_printf(p->out, "session %s enable flag = %d\n",
+                    pSession->zName, ii);
+      }
+    }else
+
+    /* .session filter GLOB ....
+    ** Set a list of GLOB patterns of table names to be excluded.
+    */
+    if( strcmp(azCmd[0], "filter")==0 ){
+      int ii, nByte;
+      if( nCmd<2 ) goto session_syntax_error;
+      if( p->nSession ){
+        for(ii=0; ii<pSession->nFilter; ii++){
+          sqlite3_free(pSession->azFilter[ii]);
+        }
+        sqlite3_free(pSession->azFilter);
+        nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
+        pSession->azFilter = sqlite3_malloc( nByte );
+        if( pSession->azFilter==0 ){
+          raw_printf(stderr, "Error: out or memory\n");
+          exit(1);
+        }
+        for(ii=1; ii<nCmd; ii++){
+          pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
+        }
+        pSession->nFilter = ii-1;
+      }
+    }else
+
+    /* .session indirect ?BOOLEAN?
+    ** Query or set the indirect flag
+    */
+    if( strcmp(azCmd[0], "indirect")==0 ){
+      int ii;
+      if( nCmd>2 ) goto session_syntax_error;
+      ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
+      if( p->nSession ){
+        ii = sqlite3session_indirect(pSession->p, ii);
+        utf8_printf(p->out, "session %s indirect flag = %d\n",
+                    pSession->zName, ii);
+      }
+    }else
+
+    /* .session isempty
+    ** Determine if the session is empty
+    */
+    if( strcmp(azCmd[0], "isempty")==0 ){
+      int ii;
+      if( nCmd!=1 ) goto session_syntax_error;
+      if( p->nSession ){
+        ii = sqlite3session_isempty(pSession->p);
+        utf8_printf(p->out, "session %s isempty flag = %d\n",
+                    pSession->zName, ii);
+      }
+    }else
+
+    /* .session list
+    ** List all currently open sessions
+    */
+    if( strcmp(azCmd[0],"list")==0 ){
+      for(i=0; i<p->nSession; i++){
+        utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
+      }
+    }else
+
+    /* .session open DB NAME
+    ** Open a new session called NAME on the attached database DB.
+    ** DB is normally "main".
+    */
+    if( strcmp(azCmd[0],"open")==0 ){
+      char *zName;
+      if( nCmd!=3 ) goto session_syntax_error;
+      zName = azCmd[2];
+      if( zName[0]==0 ) goto session_syntax_error;
+      for(i=0; i<p->nSession; i++){
+        if( strcmp(p->aSession[i].zName,zName)==0 ){
+          utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
+          goto meta_command_exit;
+        }
+      }
+      if( p->nSession>=ArraySize(p->aSession) ){
+        raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
+        goto meta_command_exit;
+      }
+      pSession = &p->aSession[p->nSession];
+      rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
+      if( rc ){
+        raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
+        rc = 0;
+        goto meta_command_exit;
+      }
+      pSession->nFilter = 0;
+      sqlite3session_table_filter(pSession->p, session_filter, pSession);
+      p->nSession++;
+      pSession->zName = sqlite3_mprintf("%s", zName);
+    }else
+    /* If no command name matches, show a syntax error */
+    session_syntax_error:
+    session_help(p);
+  }else
+#endif
 
 #ifdef SQLITE_DEBUG
   /* Undocumented commands for internal testing.  Subject to change
@@ -3786,17 +4324,18 @@ static int do_meta_command(char *zLine, ShellState *p){
   }else
 
   if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
+    static const char *const azBool[] = { "off", "on", "full", "unk" };
     int i;
     if( nArg!=1 ){
       raw_printf(stderr, "Usage: .show\n");
       rc = 1;
       goto meta_command_exit;
     }
-    utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
-    utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
+    utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
+    utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
     utf8_printf(p->out, "%12.12s: %s\n","explain",
          p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
-    utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
+    utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
     utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
     utf8_printf(p->out, "%12.12s: ", "nullvalue");
       output_c_string(p->out, p->nullValue);
@@ -3809,7 +4348,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     utf8_printf(p->out,"%12.12s: ", "rowseparator");
       output_c_string(p->out, p->rowSeparator);
       raw_printf(p->out, "\n");
-    utf8_printf(p->out, "%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
+    utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
     utf8_printf(p->out, "%12.12s: ", "width");
     for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
       raw_printf(p->out, "%d ", p->colWidth[i]);
@@ -3820,8 +4359,10 @@ static int do_meta_command(char *zLine, ShellState *p){
   if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
     if( nArg==2 ){
       p->statsOn = booleanValue(azArg[1]);
+    }else if( nArg==1 ){
+      display_stats(p->db, p, 0);
     }else{
-      raw_printf(stderr, "Usage: .stats on|off\n");
+      raw_printf(stderr, "Usage: .stats ?on|off?\n");
       rc = 1;
     }
   }else
@@ -3979,9 +4520,9 @@ static int do_meta_command(char *zLine, ShellState *p){
 
         /* sqlite3_test_control(int, db, int) */
         case SQLITE_TESTCTRL_OPTIMIZATIONS:
-        case SQLITE_TESTCTRL_RESERVE:             
+        case SQLITE_TESTCTRL_RESERVE:
           if( nArg==3 ){
-            int opt = (int)strtol(azArg[2], 0, 0);        
+            int opt = (int)strtol(azArg[2], 0, 0);
             rc2 = sqlite3_test_control(testctrl, p->db, opt);
             raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
           } else {
@@ -4005,7 +4546,7 @@ static int do_meta_command(char *zLine, ShellState *p){
           break;
 
         /* sqlite3_test_control(int, uint) */
-        case SQLITE_TESTCTRL_PENDING_BYTE:        
+        case SQLITE_TESTCTRL_PENDING_BYTE:
           if( nArg==3 ){
             unsigned int opt = (unsigned int)integerValue(azArg[2]);
             rc2 = sqlite3_test_control(testctrl, opt);
@@ -4015,13 +4556,13 @@ static int do_meta_command(char *zLine, ShellState *p){
                            " int option\n", azArg[1]);
           }
           break;
-          
+
         /* sqlite3_test_control(int, int) */
-        case SQLITE_TESTCTRL_ASSERT:              
-        case SQLITE_TESTCTRL_ALWAYS:      
-        case SQLITE_TESTCTRL_NEVER_CORRUPT:        
+        case SQLITE_TESTCTRL_ASSERT:
+        case SQLITE_TESTCTRL_ALWAYS:
+        case SQLITE_TESTCTRL_NEVER_CORRUPT:
           if( nArg==3 ){
-            int opt = booleanValue(azArg[2]);        
+            int opt = booleanValue(azArg[2]);
             rc2 = sqlite3_test_control(testctrl, opt);
             raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
           } else {
@@ -4032,9 +4573,9 @@ static int do_meta_command(char *zLine, ShellState *p){
 
         /* sqlite3_test_control(int, char *) */
 #ifdef SQLITE_N_KEYWORD
-        case SQLITE_TESTCTRL_ISKEYWORD:           
+        case SQLITE_TESTCTRL_ISKEYWORD:
           if( nArg==3 ){
-            const char *opt = azArg[2];        
+            const char *opt = azArg[2];
             rc2 = sqlite3_test_control(testctrl, opt);
             raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
           } else {
@@ -4047,7 +4588,7 @@ static int do_meta_command(char *zLine, ShellState *p){
 
         case SQLITE_TESTCTRL_IMPOSTER:
           if( nArg==5 ){
-            rc2 = sqlite3_test_control(testctrl, p->db, 
+            rc2 = sqlite3_test_control(testctrl, p->db,
                           azArg[2],
                           integerValue(azArg[3]),
                           integerValue(azArg[4]));
@@ -4057,10 +4598,10 @@ static int do_meta_command(char *zLine, ShellState *p){
           }
           break;
 
-        case SQLITE_TESTCTRL_BITVEC_TEST:         
-        case SQLITE_TESTCTRL_FAULT_INSTALL:       
-        case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: 
-        case SQLITE_TESTCTRL_SCRATCHMALLOC:       
+        case SQLITE_TESTCTRL_BITVEC_TEST:
+        case SQLITE_TESTCTRL_FAULT_INSTALL:
+        case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
+        case SQLITE_TESTCTRL_SCRATCHMALLOC:
         default:
           utf8_printf(stderr,
                       "Error: CLI support for testctrl %s not implemented\n",
@@ -4074,7 +4615,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     open_db(p, 0);
     sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
   }else
-    
+
   if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
     if( nArg==2 ){
       enableTimer = booleanValue(azArg[1]);
@@ -4087,7 +4628,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       rc = 1;
     }
   }else
-  
+
   if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
     open_db(p, 0);
     if( nArg!=2 ){
@@ -4167,7 +4708,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
       rc = 1;
       goto meta_command_exit;
-    }    
+    }
   }else
 #endif /* SQLITE_USER_AUTHENTICATION */
 
@@ -4222,7 +4763,6 @@ static int do_meta_command(char *zLine, ShellState *p){
 
 #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
   if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
-    extern int sqlite3WhereTrace;
     sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
   }else
 #endif
@@ -4399,7 +4939,7 @@ static int process_input(ShellState *p, FILE *in){
       if( rc || zErrMsg ){
         char zPrefix[100];
         if( in!=0 || !stdin_is_interactive ){
-          sqlite3_snprintf(sizeof(zPrefix), zPrefix, 
+          sqlite3_snprintf(sizeof(zPrefix), zPrefix,
                            "Error: near line %d:", startline);
         }else{
           sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
@@ -4541,7 +5081,7 @@ static void process_sqliterc(
 /*
 ** Show available command line options
 */
-static const char zOptions[] = 
+static const char zOptions[] =
   "   -ascii               set output mode to 'ascii'\n"
   "   -bail                stop after hitting an error\n"
   "   -batch               force batch I/O\n"
@@ -4579,7 +5119,7 @@ static const char zOptions[] =
 ;
 static void usage(int showDetail){
   utf8_printf(stderr,
-      "Usage: %s [OPTIONS] FILENAME [SQL]\n"  
+      "Usage: %s [OPTIONS] FILENAME [SQL]\n"
       "FILENAME is the name of an SQLite database. A new database is created\n"
       "if the file does not previously exist.\n", Argv0);
   if( showDetail ){
@@ -4645,7 +5185,20 @@ static char *cmdline_option_value(int argc, char **argv, int i){
 int _CRT_glob = 0x0001; /* See MinGW bug #2062 */
 #endif
 
+#ifndef SQLITE_SHELL_IS_UTF8
+#  if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
+#    define SQLITE_SHELL_IS_UTF8          (0)
+#  else
+#    define SQLITE_SHELL_IS_UTF8          (1)
+#  endif
+#endif
+
+#if SQLITE_SHELL_IS_UTF8
 int SQLITE_CDECL main(int argc, char **argv){
+#else
+int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
+  char **argv;
+#endif
   char *zErrMsg = 0;
   ShellState data;
   const char *zInitFile = 0;
@@ -4656,6 +5209,11 @@ int SQLITE_CDECL main(int argc, char **argv){
   int nCmd = 0;
   char **azCmd = 0;
 
+  setBinaryMode(stdin, 0);
+  setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
+  stdin_is_interactive = isatty(0);
+  stdout_is_console = isatty(1);
+
 #if USE_SYSTEM_SQLITE+0!=1
   if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
     utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
@@ -4663,12 +5221,24 @@ int SQLITE_CDECL main(int argc, char **argv){
     exit(1);
   }
 #endif
-  setBinaryMode(stdin);
-  setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
-  Argv0 = argv[0];
   main_init(&data);
-  stdin_is_interactive = isatty(0);
-  stdout_is_console = isatty(1);
+#if !SQLITE_SHELL_IS_UTF8
+  sqlite3_initialize();
+  argv = sqlite3_malloc(sizeof(argv[0])*argc);
+  if( argv==0 ){
+    raw_printf(stderr, "out of memory\n");
+    exit(1);
+  }
+  for(i=0; i<argc; i++){
+    argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
+    if( argv[i]==0 ){
+      raw_printf(stderr, "out of memory\n");
+      exit(1);
+    }
+  }
+#endif
+  assert( argc>=1 && argv && argv[0] );
+  Argv0 = argv[0];
 
   /* Make sure we have a valid signal handler early, before anything
   ** else is done.
@@ -4726,7 +5296,7 @@ int SQLITE_CDECL main(int argc, char **argv){
       zInitFile = cmdline_option_value(argc, argv, ++i);
     }else if( strcmp(z,"-batch")==0 ){
       /* Need to check for batch mode here to so we can avoid printing
-      ** informational messages (like from process_sqliterc) before 
+      ** informational messages (like from process_sqliterc) before
       ** we do the actual processing of arguments later in a second pass.
       */
       stdin_is_interactive = 0;
@@ -4867,6 +5437,8 @@ int SQLITE_CDECL main(int argc, char **argv){
       data.echoOn = 1;
     }else if( strcmp(z,"-eqp")==0 ){
       data.autoEQP = 1;
+    }else if( strcmp(z,"-eqpfull")==0 ){
+      data.autoEQP = 2;
     }else if( strcmp(z,"-stats")==0 ){
       data.statsOn = 1;
     }else if( strcmp(z,"-scanstats")==0 ){
@@ -4998,8 +5570,13 @@ int SQLITE_CDECL main(int argc, char **argv){
   }
   set_table_name(&data, 0);
   if( data.db ){
+    session_close_all(&data);
     sqlite3_close(data.db);
   }
-  sqlite3_free(data.zFreeOnClose); 
+  sqlite3_free(data.zFreeOnClose);
+#if !SQLITE_SHELL_IS_UTF8
+  for(i=0; i<argc; i++) sqlite3_free(argv[i]);
+  sqlite3_free(argv);
+#endif
   return rc;
 }
@@ -157,6 +157,7 @@ set tabledef {CREATE TABLE space_used(
    name clob,        -- Name of a table or index in the database file
    tblname clob,     -- Name of associated table
    is_index boolean, -- TRUE if it is an index, false for a table
+   is_without_rowid boolean, -- TRUE if WITHOUT ROWID table  
    nentry int,       -- Number of entries in the BTree
    leaf_entries int, -- Number of leaf entries
    depth int,        -- Depth of the b-tree
@@ -189,7 +190,7 @@ set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 }
 foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {
 
   set is_index [expr {$name!=$tblname}]
-  set idx_btree [expr {$is_index || [is_without_rowid $name]}]
+  set is_without_rowid [is_without_rowid $name]
   db eval {
     SELECT 
       sum(ncell) AS nentry,
@@ -240,6 +241,7 @@ foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {
       $name,
       $tblname,
       $is_index,
+      $is_without_rowid,
       $nentry,
       $leaf_entries,
       $depth,
@@ -335,12 +337,15 @@ proc subreport {title where showFrag} {
   # following query returns exactly one row (because it is an aggregate).
   #
   # The results of the query are stored directly by SQLite into local 
-  # variables (i.e. $nentry, $nleaf etc.).
+  # variables (i.e. $nentry, $payload etc.).
   #
   mem eval "
     SELECT
-      int(sum(nentry)) AS nentry,
-      int(sum(leaf_entries)) AS nleaf,
+      int(sum(
+        CASE WHEN (is_without_rowid OR is_index) THEN nentry 
+             ELSE leaf_entries 
+        END
+      )) AS nentry,
       int(sum(payload)) AS payload,
       int(sum(ovfl_payload)) AS ovfl_payload,
       max(mx_payload) AS mx_payload,
@@ -380,8 +385,8 @@ proc subreport {title where showFrag} {
   set storage [expr {$total_pages*$pageSize}]
   set payload_percent [percent $payload $storage {of storage consumed}]
   set total_unused [expr {$ovfl_unused+$int_unused+$leaf_unused}]
-  set avg_payload [divide $payload $nleaf]
-  set avg_unused [divide $total_unused $nleaf]
+  set avg_payload [divide $payload $nentry]
+  set avg_unused [divide $total_unused $nentry]
   if {$int_pages>0} {
     # TODO: Is this formula correct?
     set nTab [mem eval "
@@ -395,12 +400,12 @@ proc subreport {title where showFrag} {
     "]
     set avg_fanout [format %.2f $avg_fanout]
   }
-  set ovfl_cnt_percent [percent $ovfl_cnt $nleaf {of all entries}]
+  set ovfl_cnt_percent [percent $ovfl_cnt $nentry {of all entries}]
 
   # Print out the sub-report statistics.
   #
   statline {Percentage of total database} $total_pages_percent
-  statline {Number of entries} $nleaf
+  statline {Number of entries} $nentry
   statline {Bytes of storage consumed} $storage
   if {$compressed_size!=$storage} {
     set compressed_size [expr {$compressed_size+$compressOverhead*$total_pages}]
similarity index 92%
rename from pkgs/sqlite3.11.0/compat/sqlite3/sqlite3.c
rename to pkgs/sqlite3.13.0/compat/sqlite3/sqlite3.c
index 58b73d4..3e20b56 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.11.0.  By combining all the individual C code files into this 
+** version 3.13.0.  By combining all the individual C code files into this 
 ** single large file, the entire code can be compiled as a single translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
 
+/* Special Comments:
+**
+** Some comments have special meaning to the tools that measure test
+** coverage:
+**
+**    NO_TEST                     - The branches on this line are not
+**                                  measured by branch coverage.  This is
+**                                  used on lines of code that actually
+**                                  implement parts of coverage testing.
+**
+**    OPTIMIZATION-IF-TRUE        - This branch is allowed to alway be false
+**                                  and the correct answer is still obtained,
+**                                  though perhaps more slowly.
+**
+**    OPTIMIZATION-IF-FALSE       - This branch is allowed to alway be true
+**                                  and the correct answer is still obtained,
+**                                  though perhaps more slowly.
+**
+**    PREVENTS-HARMLESS-OVERREAD  - This branch prevents a buffer overread
+**                                  that would be harmless and undetectable
+**                                  if it did occur.  
+**
+** In all cases, the special comment must be enclosed in the usual
+** slash-asterisk...asterisk-slash comment marks, with no spaces between the 
+** asterisks and the comment text.
+*/
+
+/*
+** Make sure that rand_s() is available on Windows systems with MSVC 2005
+** or higher.
+*/
+#if defined(__MSVCRT__) || defined(_MSC_VER) && _MSC_VER>=1400
+#  define _CRT_RAND_S
+#endif
+
 /*
 ** Include the header file used to customize the compiler options for MSVC.
 ** This should be done first so that it can successfully prevent spurious
 #pragma warning(disable : 4210)
 #pragma warning(disable : 4232)
 #pragma warning(disable : 4244)
+#pragma warning(disable : 4267)
 #pragma warning(disable : 4305)
 #pragma warning(disable : 4306)
 #pragma warning(disable : 4702)
@@ -328,9 +364,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.11.0"
-#define SQLITE_VERSION_NUMBER 3011000
-#define SQLITE_SOURCE_ID      "2016-02-15 17:29:24 3d862f207e3adc00f78066799ac5a8c282430a5f"
+#define SQLITE_VERSION        "3.13.0"
+#define SQLITE_VERSION_NUMBER 3013000
+#define SQLITE_SOURCE_ID      "2016-05-18 10:57:30 fc49f556e48970561d7ab6a2f24fdd7d9eb81ff2"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -1445,7 +1481,7 @@ struct sqlite3_vfs {
   const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
   /*
   ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
-  ** New fields may be appended in figure versions.  The iVersion
+  ** New fields may be appended in future versions.  The iVersion
   ** value will increment whenever this happens. 
   */
 };
@@ -2039,6 +2075,20 @@ struct sqlite3_mem_methods {
 ** is enabled (using the [PRAGMA threads] command) and the amount of content
 ** to be sorted exceeds the page size times the minimum of the
 ** [PRAGMA cache_size] setting and this value.
+**
+** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
+** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
+** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
+** becomes the [statement journal] spill-to-disk threshold.  
+** [Statement journals] are held in memory until their size (in bytes)
+** exceeds this threshold, at which point they are written to disk.
+** Or if the threshold is -1, statement journals are always held
+** exclusively in memory.
+** Since many statement journals never become large, setting the spill
+** threshold to a value such as 64KiB can greatly reduce the amount of
+** I/O required to support statement rollback.
+** The default value for this setting is controlled by the
+** [SQLITE_STMTJRNL_SPILL] compile-time option.
 ** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
@@ -2066,6 +2116,7 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
 #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
 #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
+#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
@@ -2123,11 +2174,43 @@ struct sqlite3_mem_methods {
 ** following this call.  The second parameter may be a NULL pointer, in
 ** which case the trigger setting is not reported back. </dd>
 **
+** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+** <dd> ^This option is used to enable or disable the two-argument
+** version of the [fts3_tokenizer()] function which is part of the
+** [FTS3] full-text search engine extension.
+** There should be two additional arguments.
+** The first argument is an integer which is 0 to disable fts3_tokenizer() or
+** positive to enable fts3_tokenizer() or negative to leave the setting
+** unchanged.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
+** following this call.  The second parameter may be a NULL pointer, in
+** which case the new setting is not reported back. </dd>
+**
+** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+** interface independently of the [load_extension()] SQL function.
+** The [sqlite3_enable_load_extension()] API enables or disables both the
+** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
+** There should be two additional arguments.
+** When the first argument to this interface is 1, then only the C-API is
+** enabled and the SQL function remains disabled.  If the first argment to
+** this interface is 0, then both the C-API and the SQL function are disabled.
+** If the first argument is -1, then no changes are made to state of either the
+** C-API or the SQL function.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
+** is disabled or enabled following this call.  The second parameter may
+** be a NULL pointer, in which case the new setting is not reported back.
+** </dd>
+**
 ** </dl>
 */
-#define SQLITE_DBCONFIG_LOOKASIDE       1001  /* void* int int */
-#define SQLITE_DBCONFIG_ENABLE_FKEY     1002  /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_TRIGGER  1003  /* int int* */
+#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
+#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
 
 
 /*
@@ -5390,7 +5473,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
 ** ^The sqlite3_update_hook() interface registers a callback function
 ** with the [database connection] identified by the first argument
 ** to be invoked whenever a row is updated, inserted or deleted in
-** a rowid table.
+** a [rowid table].
 ** ^Any callback set by a previous call to this function
 ** for the same database connection is overridden.
 **
@@ -5429,8 +5512,8 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
 ** on the same [database connection] D, or NULL for
 ** the first call on D.
 **
-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
-** interfaces.
+** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
+** and [sqlite3_preupdate_hook()] interfaces.
 */
 SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
   sqlite3*, 
@@ -5678,9 +5761,18 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
 ** should free this memory by calling [sqlite3_free()].
 **
 ** ^Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] prior to calling this API,
+** [sqlite3_enable_load_extension()] or
+** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
+** prior to calling this API,
 ** otherwise an error will be returned.
 **
+** <b>Security warning:</b> It is recommended that the 
+** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
+** interface.  The use of the [sqlite3_enable_load_extension()] interface
+** should be avoided.  This will keep the SQL function [load_extension()]
+** disabled and prevent SQL injections from giving attackers
+** access to extension loading capabilities.
+**
 ** See also the [load_extension() SQL function].
 */
 SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
@@ -5703,6 +5795,17 @@ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
 ** ^Call the sqlite3_enable_load_extension() routine with onoff==1
 ** to turn extension loading on and call it with onoff==0 to turn
 ** it back off again.
+**
+** ^This interface enables or disables both the C-API
+** [sqlite3_load_extension()] and the SQL function [load_extension()].
+** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
+** to enable or disable only the C-API.
+**
+** <b>Security warning:</b> It is recommended that extension loading
+** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
+** rather than this interface, so the [load_extension()] SQL function
+** remains disabled. This will prevent SQL injections from giving attackers
+** access to extension loading capabilities.
 */
 SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
@@ -5946,7 +6049,7 @@ struct sqlite3_index_info {
     unsigned char omit;      /* Do not code a test for this constraint */
   } *aConstraintUsage;
   int idxNum;                /* Number used to identify the index */
-  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
+  const char *idxStr;        /* String, possibly obtained from sqlite3_malloc */
   int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
   int orderByConsumed;       /* True if output is already ordered */
   double estimatedCost;           /* Estimated cost of using this index */
@@ -7341,7 +7444,7 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
 ** an error.
 **
-** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
+** ^A call to sqlite3_backup_init() will fail, returning NULL, if 
 ** there is already a read or read-write transaction open on the 
 ** destination database.
 **
@@ -7722,7 +7825,7 @@ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...)
 ** previously registered write-ahead log callback. ^Note that the
 ** [sqlite3_wal_autocheckpoint()] interface and the
 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** those overwrite any prior [sqlite3_wal_hook()] settings.
+** overwrite any prior [sqlite3_wal_hook()] settings.
 */
 SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
   sqlite3*, 
@@ -8120,6 +8223,114 @@ SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
 SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
 
 /*
+** CAPI3REF: The pre-update hook.
+**
+** ^These interfaces are only available if SQLite is compiled using the
+** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
+**
+** ^The [sqlite3_preupdate_hook()] interface registers a callback function
+** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
+** on a [rowid table].
+** ^At most one preupdate hook may be registered at a time on a single
+** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
+** the previous setting.
+** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
+** with a NULL pointer as the second parameter.
+** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
+** the first parameter to callbacks.
+**
+** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate
+** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID]
+** tables.
+**
+** ^The second parameter to the preupdate callback is a pointer to
+** the [database connection] that registered the preupdate hook.
+** ^The third parameter to the preupdate callback is one of the constants
+** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to indentify the
+** kind of update operation that is about to occur.
+** ^(The fourth parameter to the preupdate callback is the name of the
+** database within the database connection that is being modified.  This
+** will be "main" for the main database or "temp" for TEMP tables or 
+** the name given after the AS keyword in the [ATTACH] statement for attached
+** databases.)^
+** ^The fifth parameter to the preupdate callback is the name of the
+** table that is being modified.
+** ^The sixth parameter to the preupdate callback is the initial [rowid] of the
+** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is
+** undefined for SQLITE_INSERT changes.
+** ^The seventh parameter to the preupdate callback is the final [rowid] of
+** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is
+** undefined for SQLITE_DELETE changes.
+**
+** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
+** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
+** provide additional information about a preupdate event. These routines
+** may only be called from within a preupdate callback.  Invoking any of
+** these routines from outside of a preupdate callback or with a
+** [database connection] pointer that is different from the one supplied
+** to the preupdate callback results in undefined and probably undesirable
+** behavior.
+**
+** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
+** in the row that is being inserted, updated, or deleted.
+**
+** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row before it is updated.  The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
+** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
+** behavior is undefined.  The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row after it is updated.  The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
+** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
+** behavior is undefined.  The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
+** callback was invoked as a result of a direct insert, update, or delete
+** operation; or 1 for inserts, updates, or deletes invoked by top-level 
+** triggers; or 2 for changes resulting from triggers called by top-level
+** triggers; and so forth.
+**
+** See also:  [sqlite3_update_hook()]
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_preupdate_hook(
+  sqlite3 *db,
+  void(*xPreUpdate)(
+    void *pCtx,                   /* Copy of third arg to preupdate_hook() */
+    sqlite3 *db,                  /* Database handle */
+    int op,                       /* SQLITE_UPDATE, DELETE or INSERT */
+    char const *zDb,              /* Database name */
+    char const *zName,            /* Table name */
+    sqlite3_int64 iKey1,          /* Rowid of row about to be deleted/updated */
+    sqlite3_int64 iKey2           /* New rowid value (for a rowid UPDATE) */
+  ),
+  void*
+);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_count(sqlite3 *);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_depth(sqlite3 *);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+
+/*
+** CAPI3REF: Low-level system error code
+**
+** ^Attempt to return the underlying operating system error code or error
+** number that caused the most recent I/O error or failure to open a file.
+** The return value is OS-dependent.  For example, on unix systems, after
+** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
+** called to get back the underlying "errno" that caused the problem, such
+** as ENOSPC, EAUTH, EISDIR, and so forth.  
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*);
+
+/*
 ** CAPI3REF: Database Snapshot
 ** KEYWORDS: {snapshot}
 ** EXPERIMENTAL
@@ -8177,17 +8388,30 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
 ** CAPI3REF: Start a read transaction on an historical snapshot
 ** EXPERIMENTAL
 **
-** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
-** read transaction that is currently open on schema S of
-** [database connection] D so that it refers to historical [snapshot] P.
+** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
+** read transaction for schema S of
+** [database connection] D such that the read transaction
+** refers to historical [snapshot] P, rather than the most
+** recent change to the database.
 ** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
 ** or an appropriate [error code] if it fails.
 **
 ** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
-** the first operation, apart from other sqlite3_snapshot_open() calls,
-** following the [BEGIN] that starts a new read transaction.
-** ^A [snapshot] will fail to open if it has been overwritten by a 
-** [checkpoint].  
+** the first operation following the [BEGIN] that takes the schema S
+** out of [autocommit mode].
+** ^In other words, schema S must not currently be in
+** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
+** database connection D must be out of [autocommit mode].
+** ^A [snapshot] will fail to open if it has been overwritten by a
+** [checkpoint].
+** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+** database connection D does not know that the database file for
+** schema S is in [WAL mode].  A database connection might not know
+** that the database file is in [WAL mode] if there has been no prior
+** I/O on that database connection, or if the database entered [WAL mode] 
+** after the most recent I/O on the database connection.)^
+** (Hint: Run "[PRAGMA application_id]" against a newly opened
+** database connection in order to make it ready to use snapshots.)
 **
 ** The [sqlite3_snapshot_open()] interface is only available when the
 ** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
@@ -8212,6 +8436,33 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
 SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot*);
 
 /*
+** CAPI3REF: Compare the ages of two snapshot handles.
+** EXPERIMENTAL
+**
+** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+** of two valid snapshot handles. 
+**
+** If the two snapshot handles are not associated with the same database 
+** file, the result of the comparison is undefined. 
+**
+** Additionally, the result of the comparison is only valid if both of the
+** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
+** last time the wal file was deleted. The wal file is deleted when the
+** database is changed back to rollback mode or when the number of database
+** clients drops to zero. If either snapshot handle was obtained before the 
+** wal file was last deleted, the value returned by this function 
+** is undefined.
+**
+** Otherwise, this API returns a negative value if P1 refers to an older
+** snapshot than P2, zero if the two handles refer to the same database
+** snapshot, and a positive value if P1 is a newer snapshot than P2.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_cmp(
+  sqlite3_snapshot *p1,
+  sqlite3_snapshot *p2
+);
+
+/*
 ** Undo the hack that converts floating point types to integer for
 ** builds on processors without floating point support.
 */
@@ -8224,6 +8475,7 @@ SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3
 #endif
 #endif /* _SQLITE3_H_ */
 
+/******** Begin file sqlite3rtree.h *********/
 /*
 ** 2010 August 30
 **
@@ -8341,6 +8593,1287 @@ struct sqlite3_rtree_query_info {
 
 #endif  /* ifndef _SQLITE3RTREE_H_ */
 
+/******** End of sqlite3rtree.h *********/
+/******** Begin file sqlite3session.h *********/
+
+#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
+#define __SQLITESESSION_H_ 1
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#if 0
+extern "C" {
+#endif
+
+
+/*
+** CAPI3REF: Session Object Handle
+*/
+typedef struct sqlite3_session sqlite3_session;
+
+/*
+** CAPI3REF: Changeset Iterator Handle
+*/
+typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
+
+/*
+** CAPI3REF: Create A New Session Object
+**
+** Create a new session object attached to database handle db. If successful,
+** a pointer to the new object is written to *ppSession and SQLITE_OK is
+** returned. If an error occurs, *ppSession is set to NULL and an SQLite
+** error code (e.g. SQLITE_NOMEM) is returned.
+**
+** It is possible to create multiple session objects attached to a single
+** database handle.
+**
+** Session objects created using this function should be deleted using the
+** [sqlite3session_delete()] function before the database handle that they
+** are attached to is itself closed. If the database handle is closed before
+** the session object is deleted, then the results of calling any session
+** module function, including [sqlite3session_delete()] on the session object
+** are undefined.
+**
+** Because the session module uses the [sqlite3_preupdate_hook()] API, it
+** is not possible for an application to register a pre-update hook on a
+** database handle that has one or more session objects attached. Nor is
+** it possible to create a session object attached to a database handle for
+** which a pre-update hook is already defined. The results of attempting 
+** either of these things are undefined.
+**
+** The session object will be used to create changesets for tables in
+** database zDb, where zDb is either "main", or "temp", or the name of an
+** attached database. It is not an error if database zDb is not attached
+** to the database when the session object is created.
+*/
+int sqlite3session_create(
+  sqlite3 *db,                    /* Database handle */
+  const char *zDb,                /* Name of db (e.g. "main") */
+  sqlite3_session **ppSession     /* OUT: New session object */
+);
+
+/*
+** CAPI3REF: Delete A Session Object
+**
+** Delete a session object previously allocated using 
+** [sqlite3session_create()]. Once a session object has been deleted, the
+** results of attempting to use pSession with any other session module
+** function are undefined.
+**
+** Session objects must be deleted before the database handle to which they
+** are attached is closed. Refer to the documentation for 
+** [sqlite3session_create()] for details.
+*/
+void sqlite3session_delete(sqlite3_session *pSession);
+
+
+/*
+** CAPI3REF: Enable Or Disable A Session Object
+**
+** Enable or disable the recording of changes by a session object. When
+** enabled, a session object records changes made to the database. When
+** disabled - it does not. A newly created session object is enabled.
+** Refer to the documentation for [sqlite3session_changeset()] for further
+** details regarding how enabling and disabling a session object affects
+** the eventual changesets.
+**
+** Passing zero to this function disables the session. Passing a value
+** greater than zero enables it. Passing a value less than zero is a 
+** no-op, and may be used to query the current state of the session.
+**
+** The return value indicates the final state of the session object: 0 if 
+** the session is disabled, or 1 if it is enabled.
+*/
+int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
+
+/*
+** CAPI3REF: Set Or Clear the Indirect Change Flag
+**
+** Each change recorded by a session object is marked as either direct or
+** indirect. A change is marked as indirect if either:
+**
+** <ul>
+**   <li> The session object "indirect" flag is set when the change is
+**        made, or
+**   <li> The change is made by an SQL trigger or foreign key action 
+**        instead of directly as a result of a users SQL statement.
+** </ul>
+**
+** If a single row is affected by more than one operation within a session,
+** then the change is considered indirect if all operations meet the criteria
+** for an indirect change above, or direct otherwise.
+**
+** This function is used to set, clear or query the session object indirect
+** flag.  If the second argument passed to this function is zero, then the
+** indirect flag is cleared. If it is greater than zero, the indirect flag
+** is set. Passing a value less than zero does not modify the current value
+** of the indirect flag, and may be used to query the current state of the 
+** indirect flag for the specified session object.
+**
+** The return value indicates the final state of the indirect flag: 0 if 
+** it is clear, or 1 if it is set.
+*/
+int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
+
+/*
+** CAPI3REF: Attach A Table To A Session Object
+**
+** If argument zTab is not NULL, then it is the name of a table to attach
+** to the session object passed as the first argument. All subsequent changes 
+** made to the table while the session object is enabled will be recorded. See 
+** documentation for [sqlite3session_changeset()] for further details.
+**
+** Or, if argument zTab is NULL, then changes are recorded for all tables
+** in the database. If additional tables are added to the database (by 
+** executing "CREATE TABLE" statements) after this call is made, changes for 
+** the new tables are also recorded.
+**
+** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
+** defined as part of their CREATE TABLE statement. It does not matter if the 
+** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
+** KEY may consist of a single column, or may be a composite key.
+** 
+** It is not an error if the named table does not exist in the database. Nor
+** is it an error if the named table does not have a PRIMARY KEY. However,
+** no changes will be recorded in either of these scenarios.
+**
+** Changes are not recorded for individual rows that have NULL values stored
+** in one or more of their PRIMARY KEY columns.
+**
+** SQLITE_OK is returned if the call completes without error. Or, if an error 
+** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
+*/
+int sqlite3session_attach(
+  sqlite3_session *pSession,      /* Session object */
+  const char *zTab                /* Table name */
+);
+
+/*
+** CAPI3REF: Set a table filter on a Session Object.
+**
+** The second argument (xFilter) is the "filter callback". For changes to rows 
+** in tables that are not attached to the Session oject, the filter is called
+** to determine whether changes to the table's rows should be tracked or not. 
+** If xFilter returns 0, changes is not tracked. Note that once a table is 
+** attached, xFilter will not be called again.
+*/
+void sqlite3session_table_filter(
+  sqlite3_session *pSession,      /* Session object */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of third arg to _filter_table() */
+    const char *zTab              /* Table name */
+  ),
+  void *pCtx                      /* First argument passed to xFilter */
+);
+
+/*
+** CAPI3REF: Generate A Changeset From A Session Object
+**
+** Obtain a changeset containing changes to the tables attached to the 
+** session object passed as the first argument. If successful, 
+** set *ppChangeset to point to a buffer containing the changeset 
+** and *pnChangeset to the size of the changeset in bytes before returning
+** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
+** zero and return an SQLite error code.
+**
+** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
+** each representing a change to a single row of an attached table. An INSERT
+** change contains the values of each field of a new database row. A DELETE
+** contains the original values of each field of a deleted database row. An
+** UPDATE change contains the original values of each field of an updated
+** database row along with the updated values for each updated non-primary-key
+** column. It is not possible for an UPDATE change to represent a change that
+** modifies the values of primary key columns. If such a change is made, it
+** is represented in a changeset as a DELETE followed by an INSERT.
+**
+** Changes are not recorded for rows that have NULL values stored in one or 
+** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
+** no corresponding change is present in the changesets returned by this
+** function. If an existing row with one or more NULL values stored in
+** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
+** only an INSERT is appears in the changeset. Similarly, if an existing row
+** with non-NULL PRIMARY KEY values is updated so that one or more of its
+** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
+** DELETE change only.
+**
+** The contents of a changeset may be traversed using an iterator created
+** using the [sqlite3changeset_start()] API. A changeset may be applied to
+** a database with a compatible schema using the [sqlite3changeset_apply()]
+** API.
+**
+** Within a changeset generated by this function, all changes related to a
+** single table are grouped together. In other words, when iterating through
+** a changeset or when applying a changeset to a database, all changes related
+** to a single table are processed before moving on to the next table. Tables
+** are sorted in the same order in which they were attached (or auto-attached)
+** to the sqlite3_session object. The order in which the changes related to
+** a single table are stored is undefined.
+**
+** Following a successful call to this function, it is the responsibility of
+** the caller to eventually free the buffer that *ppChangeset points to using
+** [sqlite3_free()].
+**
+** <h3>Changeset Generation</h3>
+**
+** Once a table has been attached to a session object, the session object
+** records the primary key values of all new rows inserted into the table.
+** It also records the original primary key and other column values of any
+** deleted or updated rows. For each unique primary key value, data is only
+** recorded once - the first time a row with said primary key is inserted,
+** updated or deleted in the lifetime of the session.
+**
+** There is one exception to the previous paragraph: when a row is inserted,
+** updated or deleted, if one or more of its primary key columns contain a
+** NULL value, no record of the change is made.
+**
+** The session object therefore accumulates two types of records - those
+** that consist of primary key values only (created when the user inserts
+** a new record) and those that consist of the primary key values and the
+** original values of other table columns (created when the users deletes
+** or updates a record).
+**
+** When this function is called, the requested changeset is created using
+** both the accumulated records and the current contents of the database
+** file. Specifically:
+**
+** <ul>
+**   <li> For each record generated by an insert, the database is queried
+**        for a row with a matching primary key. If one is found, an INSERT
+**        change is added to the changeset. If no such row is found, no change 
+**        is added to the changeset.
+**
+**   <li> For each record generated by an update or delete, the database is 
+**        queried for a row with a matching primary key. If such a row is
+**        found and one or more of the non-primary key fields have been
+**        modified from their original values, an UPDATE change is added to 
+**        the changeset. Or, if no such row is found in the table, a DELETE 
+**        change is added to the changeset. If there is a row with a matching
+**        primary key in the database, but all fields contain their original
+**        values, no change is added to the changeset.
+** </ul>
+**
+** This means, amongst other things, that if a row is inserted and then later
+** deleted while a session object is active, neither the insert nor the delete
+** will be present in the changeset. Or if a row is deleted and then later a 
+** row with the same primary key values inserted while a session object is
+** active, the resulting changeset will contain an UPDATE change instead of
+** a DELETE and an INSERT.
+**
+** When a session object is disabled (see the [sqlite3session_enable()] API),
+** it does not accumulate records when rows are inserted, updated or deleted.
+** This may appear to have some counter-intuitive effects if a single row
+** is written to more than once during a session. For example, if a row
+** is inserted while a session object is enabled, then later deleted while 
+** the same session object is disabled, no INSERT record will appear in the
+** changeset, even though the delete took place while the session was disabled.
+** Or, if one field of a row is updated while a session is disabled, and 
+** another field of the same row is updated while the session is enabled, the
+** resulting changeset will contain an UPDATE change that updates both fields.
+*/
+int sqlite3session_changeset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
+  void **ppChangeset              /* OUT: Buffer containing changeset */
+);
+
+/*
+** CAPI3REF: Load The Difference Between Tables Into A Session 
+**
+** If it is not already attached to the session object passed as the first
+** argument, this function attaches table zTbl in the same manner as the
+** [sqlite3session_attach()] function. If zTbl does not exist, or if it
+** does not have a primary key, this function is a no-op (but does not return
+** an error).
+**
+** Argument zFromDb must be the name of a database ("main", "temp" etc.)
+** attached to the same database handle as the session object that contains 
+** a table compatible with the table attached to the session by this function.
+** A table is considered compatible if it:
+**
+** <ul>
+**   <li> Has the same name,
+**   <li> Has the same set of columns declared in the same order, and
+**   <li> Has the same PRIMARY KEY definition.
+** </ul>
+**
+** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
+** are compatible but do not have any PRIMARY KEY columns, it is not an error
+** but no changes are added to the session object. As with other session
+** APIs, tables without PRIMARY KEYs are simply ignored.
+**
+** This function adds a set of changes to the session object that could be
+** used to update the table in database zFrom (call this the "from-table") 
+** so that its content is the same as the table attached to the session 
+** object (call this the "to-table"). Specifically:
+**
+** <ul>
+**   <li> For each row (primary key) that exists in the to-table but not in 
+**     the from-table, an INSERT record is added to the session object.
+**
+**   <li> For each row (primary key) that exists in the to-table but not in 
+**     the from-table, a DELETE record is added to the session object.
+**
+**   <li> For each row (primary key) that exists in both tables, but features 
+**     different in each, an UPDATE record is added to the session.
+** </ul>
+**
+** To clarify, if this function is called and then a changeset constructed
+** using [sqlite3session_changeset()], then after applying that changeset to 
+** database zFrom the contents of the two compatible tables would be 
+** identical.
+**
+** It an error if database zFrom does not exist or does not contain the
+** required compatible table.
+**
+** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite
+** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
+** may be set to point to a buffer containing an English language error 
+** message. It is the responsibility of the caller to free this buffer using
+** sqlite3_free().
+*/
+int sqlite3session_diff(
+  sqlite3_session *pSession,
+  const char *zFromDb,
+  const char *zTbl,
+  char **pzErrMsg
+);
+
+
+/*
+** CAPI3REF: Generate A Patchset From A Session Object
+**
+** The differences between a patchset and a changeset are that:
+**
+** <ul>
+**   <li> DELETE records consist of the primary key fields only. The 
+**        original values of other fields are omitted.
+**   <li> The original values of any modified fields are omitted from 
+**        UPDATE records.
+** </ul>
+**
+** A patchset blob may be used with up to date versions of all 
+** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), 
+** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
+** attempting to use a patchset blob with old versions of the
+** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. 
+**
+** Because the non-primary key "old.*" fields are omitted, no 
+** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
+** is passed to the sqlite3changeset_apply() API. Other conflict types work
+** in the same way as for changesets.
+**
+** Changes within a patchset are ordered in the same way as for changesets
+** generated by the sqlite3session_changeset() function (i.e. all changes for
+** a single table are grouped together, tables appear in the order in which
+** they were attached to the session object).
+*/
+int sqlite3session_patchset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
+  void **ppPatchset               /* OUT: Buffer containing changeset */
+);
+
+/*
+** CAPI3REF: Test if a changeset has recorded any changes.
+**
+** Return non-zero if no changes to attached tables have been recorded by 
+** the session object passed as the first argument. Otherwise, if one or 
+** more changes have been recorded, return zero.
+**
+** Even if this function returns zero, it is possible that calling
+** [sqlite3session_changeset()] on the session handle may still return a
+** changeset that contains no changes. This can happen when a row in 
+** an attached table is modified and then later on the original values 
+** are restored. However, if this function returns non-zero, then it is
+** guaranteed that a call to sqlite3session_changeset() will return a 
+** changeset containing zero changes.
+*/
+int sqlite3session_isempty(sqlite3_session *pSession);
+
+/*
+** CAPI3REF: Create An Iterator To Traverse A Changeset 
+**
+** Create an iterator used to iterate through the contents of a changeset.
+** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+** is returned. Otherwise, if an error occurs, *pp is set to zero and an
+** SQLite error code is returned.
+**
+** The following functions can be used to advance and query a changeset 
+** iterator created by this function:
+**
+** <ul>
+**   <li> [sqlite3changeset_next()]
+**   <li> [sqlite3changeset_op()]
+**   <li> [sqlite3changeset_new()]
+**   <li> [sqlite3changeset_old()]
+** </ul>
+**
+** It is the responsibility of the caller to eventually destroy the iterator
+** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
+** changeset (pChangeset) must remain valid until after the iterator is
+** destroyed.
+**
+** Assuming the changeset blob was created by one of the
+** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
+** [sqlite3changeset_invert()] functions, all changes within the changeset 
+** that apply to a single table are grouped together. This means that when 
+** an application iterates through a changeset using an iterator created by 
+** this function, all changes that relate to a single table are visted 
+** consecutively. There is no chance that the iterator will visit a change 
+** the applies to table X, then one for table Y, and then later on visit 
+** another change for table X.
+*/
+int sqlite3changeset_start(
+  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+  int nChangeset,                 /* Size of changeset blob in bytes */
+  void *pChangeset                /* Pointer to blob containing changeset */
+);
+
+
+/*
+** CAPI3REF: Advance A Changeset Iterator
+**
+** This function may only be used with iterators created by function
+** [sqlite3changeset_start()]. If it is called on an iterator passed to
+** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
+** is returned and the call has no effect.
+**
+** Immediately after an iterator is created by sqlite3changeset_start(), it
+** does not point to any change in the changeset. Assuming the changeset
+** is not empty, the first call to this function advances the iterator to
+** point to the first change in the changeset. Each subsequent call advances
+** the iterator to point to the next change in the changeset (if any). If
+** no error occurs and the iterator points to a valid change after a call
+** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. 
+** Otherwise, if all changes in the changeset have already been visited,
+** SQLITE_DONE is returned.
+**
+** If an error occurs, an SQLite error code is returned. Possible error 
+** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or 
+** SQLITE_NOMEM.
+*/
+int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
+** is not the case, this function returns [SQLITE_MISUSE].
+**
+** If argument pzTab is not NULL, then *pzTab is set to point to a
+** nul-terminated utf-8 encoded string containing the name of the table
+** affected by the current change. The buffer remains valid until either
+** sqlite3changeset_next() is called on the iterator or until the 
+** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
+** set to the number of columns in the table affected by the change. If
+** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** is an indirect change, or false (0) otherwise. See the documentation for
+** [sqlite3session_indirect()] for a description of direct and indirect
+** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
+** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the 
+** type of change that the iterator currently points to.
+**
+** If no error occurs, SQLITE_OK is returned. If an error does occur, an
+** SQLite error code is returned. The values of the output variables may not
+** be trusted in this case.
+*/
+int sqlite3changeset_op(
+  sqlite3_changeset_iter *pIter,  /* Iterator object */
+  const char **pzTab,             /* OUT: Pointer to table name */
+  int *pnCol,                     /* OUT: Number of columns in table */
+  int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
+  int *pbIndirect                 /* OUT: True for an 'indirect' change */
+);
+
+/*
+** CAPI3REF: Obtain The Primary Key Definition Of A Table
+**
+** For each modified table, a changeset includes the following:
+**
+** <ul>
+**   <li> The number of columns in the table, and
+**   <li> Which of those columns make up the tables PRIMARY KEY.
+** </ul>
+**
+** This function is used to find which columns comprise the PRIMARY KEY of
+** the table modified by the change that iterator pIter currently points to.
+** If successful, *pabPK is set to point to an array of nCol entries, where
+** nCol is the number of columns in the table. Elements of *pabPK are set to
+** 0x01 if the corresponding column is part of the tables primary key, or
+** 0x00 if it is not.
+**
+** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
+** in the table.
+**
+** If this function is called when the iterator does not point to a valid
+** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
+** SQLITE_OK is returned and the output variables populated as described
+** above.
+*/
+int sqlite3changeset_pk(
+  sqlite3_changeset_iter *pIter,  /* Iterator object */
+  unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
+  int *pnCol                      /* OUT: Number of entries in output array */
+);
+
+/*
+** CAPI3REF: Obtain old.* Values From A Changeset Iterator
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** original row values stored as part of the UPDATE or DELETE change and
+** returns SQLITE_OK. The name of the function comes from the fact that this 
+** is similar to the "old.*" columns available to update or delete triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+int sqlite3changeset_old(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain new.* Values From A Changeset Iterator
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** new row values stored as part of the UPDATE or INSERT change and
+** returns SQLITE_OK. If the change is an UPDATE and does not include
+** a new value for the requested column, *ppValue is set to NULL and 
+** SQLITE_OK returned. The name of the function comes from the fact that 
+** this is similar to the "new.*" columns available to update or delete 
+** triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+int sqlite3changeset_new(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
+**
+** This function should only be used with iterator objects passed to a
+** conflict-handler callback by [sqlite3changeset_apply()] with either
+** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
+** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
+** is set to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the 
+** "conflicting row" associated with the current conflict-handler callback
+** and returns SQLITE_OK.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+int sqlite3changeset_conflict(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: Value from conflicting row */
+);
+
+/*
+** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
+**
+** This function may only be called with an iterator passed to an
+** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+** it sets the output variable to the total number of known foreign key
+** violations in the destination database and returns SQLITE_OK.
+**
+** In all other cases this function returns SQLITE_MISUSE.
+*/
+int sqlite3changeset_fk_conflicts(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int *pnOut                      /* OUT: Number of FK violations */
+);
+
+
+/*
+** CAPI3REF: Finalize A Changeset Iterator
+**
+** This function is used to finalize an iterator allocated with
+** [sqlite3changeset_start()].
+**
+** This function should only be called on iterators created using the
+** [sqlite3changeset_start()] function. If an application calls this
+** function with an iterator passed to a conflict-handler by
+** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
+** call has no effect.
+**
+** If an error was encountered within a call to an sqlite3changeset_xxx()
+** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an 
+** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
+** to that error is returned by this function. Otherwise, SQLITE_OK is
+** returned. This is to allow the following pattern (pseudo-code):
+**
+**   sqlite3changeset_start();
+**   while( SQLITE_ROW==sqlite3changeset_next() ){
+**     // Do something with change.
+**   }
+**   rc = sqlite3changeset_finalize();
+**   if( rc!=SQLITE_OK ){
+**     // An error has occurred 
+**   }
+*/
+int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Invert A Changeset
+**
+** This function is used to "invert" a changeset object. Applying an inverted
+** changeset to a database reverses the effects of applying the uninverted
+** changeset. Specifically:
+**
+** <ul>
+**   <li> Each DELETE change is changed to an INSERT, and
+**   <li> Each INSERT change is changed to a DELETE, and
+**   <li> For each UPDATE change, the old.* and new.* values are exchanged.
+** </ul>
+**
+** This function does not change the order in which changes appear within
+** the changeset. It merely reverses the sense of each individual change.
+**
+** If successful, a pointer to a buffer containing the inverted changeset
+** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
+** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
+** zeroed and an SQLite error code returned.
+**
+** It is the responsibility of the caller to eventually call sqlite3_free()
+** on the *ppOut pointer to free the buffer allocation following a successful 
+** call to this function.
+**
+** WARNING/TODO: This function currently assumes that the input is a valid
+** changeset. If it is not, the results are undefined.
+*/
+int sqlite3changeset_invert(
+  int nIn, const void *pIn,       /* Input changeset */
+  int *pnOut, void **ppOut        /* OUT: Inverse of input */
+);
+
+/*
+** CAPI3REF: Concatenate Two Changeset Objects
+**
+** This function is used to concatenate two changesets, A and B, into a 
+** single changeset. The result is a changeset equivalent to applying
+** changeset A followed by changeset B. 
+**
+** This function combines the two input changesets using an 
+** sqlite3_changegroup object. Calling it produces similar results as the
+** following code fragment:
+**
+**   sqlite3_changegroup *pGrp;
+**   rc = sqlite3_changegroup_new(&pGrp);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
+**   if( rc==SQLITE_OK ){
+**     rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
+**   }else{
+**     *ppOut = 0;
+**     *pnOut = 0;
+**   }
+**
+** Refer to the sqlite3_changegroup documentation below for details.
+*/
+int sqlite3changeset_concat(
+  int nA,                         /* Number of bytes in buffer pA */
+  void *pA,                       /* Pointer to buffer containing changeset A */
+  int nB,                         /* Number of bytes in buffer pB */
+  void *pB,                       /* Pointer to buffer containing changeset B */
+  int *pnOut,                     /* OUT: Number of bytes in output changeset */
+  void **ppOut                    /* OUT: Buffer containing output changeset */
+);
+
+
+/*
+** Changegroup handle.
+*/
+typedef struct sqlite3_changegroup sqlite3_changegroup;
+
+/*
+** CAPI3REF: Combine two or more changesets into a single changeset.
+**
+** An sqlite3_changegroup object is used to combine two or more changesets
+** (or patchsets) into a single changeset (or patchset). A single changegroup
+** object may combine changesets or patchsets, but not both. The output is
+** always in the same format as the input.
+**
+** If successful, this function returns SQLITE_OK and populates (*pp) with
+** a pointer to a new sqlite3_changegroup object before returning. The caller
+** should eventually free the returned object using a call to 
+** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
+** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
+**
+** The usual usage pattern for an sqlite3_changegroup object is as follows:
+**
+** <ul>
+**   <li> It is created using a call to sqlite3changegroup_new().
+**
+**   <li> Zero or more changesets (or patchsets) are added to the object
+**        by calling sqlite3changegroup_add().
+**
+**   <li> The result of combining all input changesets together is obtained 
+**        by the application via a call to sqlite3changegroup_output().
+**
+**   <li> The object is deleted using a call to sqlite3changegroup_delete().
+** </ul>
+**
+** Any number of calls to add() and output() may be made between the calls to
+** new() and delete(), and in any order.
+**
+** As well as the regular sqlite3changegroup_add() and 
+** sqlite3changegroup_output() functions, also available are the streaming
+** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
+*/
+int sqlite3changegroup_new(sqlite3_changegroup **pp);
+
+/*
+** Add all changes within the changeset (or patchset) in buffer pData (size
+** nData bytes) to the changegroup. 
+**
+** If the buffer contains a patchset, then all prior calls to this function
+** on the same changegroup object must also have specified patchsets. Or, if
+** the buffer contains a changeset, so must have the earlier calls to this
+** function. Otherwise, SQLITE_ERROR is returned and no changes are added
+** to the changegroup.
+**
+** Rows within the changeset and changegroup are identified by the values in
+** their PRIMARY KEY columns. A change in the changeset is considered to
+** apply to the same row as a change already present in the changegroup if
+** the two rows have the same primary key.
+**
+** Changes to rows that that do not already appear in the changegroup are
+** simply copied into it. Or, if both the new changeset and the changegroup
+** contain changes that apply to a single row, the final contents of the
+** changegroup depends on the type of each change, as follows:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+**   <tr><th style="white-space:pre">Existing Change  </th>
+**       <th style="white-space:pre">New Change       </th>
+**       <th>Output Change
+**   <tr><td>INSERT <td>INSERT <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>INSERT <td>UPDATE <td>
+**       The INSERT change remains in the changegroup. The values in the 
+**       INSERT change are modified as if the row was inserted by the
+**       existing change and then updated according to the new change.
+**   <tr><td>INSERT <td>DELETE <td>
+**       The existing INSERT is removed from the changegroup. The DELETE is
+**       not added.
+**   <tr><td>UPDATE <td>INSERT <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>UPDATE <td>UPDATE <td>
+**       The existing UPDATE remains within the changegroup. It is amended 
+**       so that the accompanying values are as if the row was updated once 
+**       by the existing change and then again by the new change.
+**   <tr><td>UPDATE <td>DELETE <td>
+**       The existing UPDATE is replaced by the new DELETE within the
+**       changegroup.
+**   <tr><td>DELETE <td>INSERT <td>
+**       If one or more of the column values in the row inserted by the
+**       new change differ from those in the row deleted by the existing 
+**       change, the existing DELETE is replaced by an UPDATE within the
+**       changegroup. Otherwise, if the inserted row is exactly the same 
+**       as the deleted row, the existing DELETE is simply discarded.
+**   <tr><td>DELETE <td>UPDATE <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>DELETE <td>DELETE <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+** </table>
+**
+** If the new changeset contains changes to a table that is already present
+** in the changegroup, then the number of columns and the position of the
+** primary key columns for the table must be consistent. If this is not the
+** case, this function fails with SQLITE_SCHEMA. If the input changeset
+** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
+** returned. Or, if an out-of-memory condition occurs during processing, this
+** function returns SQLITE_NOMEM. In all cases, if an error occurs the
+** final contents of the changegroup is undefined.
+**
+** If no error occurs, SQLITE_OK is returned.
+*/
+int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+
+/*
+** Obtain a buffer containing a changeset (or patchset) representing the
+** current contents of the changegroup. If the inputs to the changegroup
+** were themselves changesets, the output is a changeset. Or, if the
+** inputs were patchsets, the output is also a patchset.
+**
+** As with the output of the sqlite3session_changeset() and
+** sqlite3session_patchset() functions, all changes related to a single
+** table are grouped together in the output of this function. Tables appear
+** in the same order as for the very first changeset added to the changegroup.
+** If the second or subsequent changesets added to the changegroup contain
+** changes for tables that do not appear in the first changeset, they are
+** appended onto the end of the output changeset, again in the order in
+** which they are first encountered.
+**
+** If an error occurs, an SQLite error code is returned and the output
+** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
+** is returned and the output variables are set to the size of and a 
+** pointer to the output buffer, respectively. In this case it is the
+** responsibility of the caller to eventually free the buffer using a
+** call to sqlite3_free().
+*/
+int sqlite3changegroup_output(
+  sqlite3_changegroup*,
+  int *pnData,                    /* OUT: Size of output buffer in bytes */
+  void **ppData                   /* OUT: Pointer to output buffer */
+);
+
+/*
+** Delete a changegroup object.
+*/
+void sqlite3changegroup_delete(sqlite3_changegroup*);
+
+/*
+** CAPI3REF: Apply A Changeset To A Database
+**
+** Apply a changeset to a database. This function attempts to update the
+** "main" database attached to handle db with the changes found in the
+** changeset passed via the second and third arguments.
+**
+** The fourth argument (xFilter) passed to this function is the "filter
+** callback". If it is not NULL, then for each table affected by at least one
+** change in the changeset, the filter callback is invoked with
+** the table name as the second argument, and a copy of the context pointer
+** passed as the sixth argument to this function as the first. If the "filter
+** callback" returns zero, then no attempt is made to apply any changes to 
+** the table. Otherwise, if the return value is non-zero or the xFilter
+** argument to this function is NULL, all changes related to the table are
+** attempted.
+**
+** For each table that is not excluded by the filter callback, this function 
+** tests that the target database contains a compatible table. A table is 
+** considered compatible if all of the following are true:
+**
+** <ul>
+**   <li> The table has the same name as the name recorded in the 
+**        changeset, and
+**   <li> The table has the same number of columns as recorded in the 
+**        changeset, and
+**   <li> The table has primary key columns in the same position as 
+**        recorded in the changeset.
+** </ul>
+**
+** If there is no compatible table, it is not an error, but none of the
+** changes associated with the table are applied. A warning message is issued
+** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
+** one such warning is issued for each table in the changeset.
+**
+** For each change for which there is a compatible table, an attempt is made 
+** to modify the table contents according to the UPDATE, INSERT or DELETE 
+** change. If a change cannot be applied cleanly, the conflict handler 
+** function passed as the fifth argument to sqlite3changeset_apply() may be 
+** invoked. A description of exactly when the conflict handler is invoked for 
+** each type of change is below.
+**
+** Unlike the xFilter argument, xConflict may not be passed NULL. The results
+** of passing anything other than a valid function pointer as the xConflict
+** argument are undefined.
+**
+** Each time the conflict handler function is invoked, it must return one
+** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or 
+** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
+** if the second argument passed to the conflict handler is either
+** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
+** returns an illegal value, any changes already made are rolled back and
+** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different 
+** actions are taken by sqlite3changeset_apply() depending on the value
+** returned by each invocation of the conflict-handler function. Refer to
+** the documentation for the three 
+** [SQLITE_CHANGESET_OMIT|available return values] for details.
+**
+** <dl>
+** <dt>DELETE Changes<dd>
+**   For each DELETE change, this function checks if the target database 
+**   contains a row with the same primary key value (or values) as the 
+**   original row values stored in the changeset. If it does, and the values 
+**   stored in all non-primary key columns also match the values stored in 
+**   the changeset the row is deleted from the target database.
+**
+**   If a row with matching primary key values is found, but one or more of
+**   the non-primary key fields contains a value different from the original
+**   row value stored in the changeset, the conflict-handler function is
+**   invoked with [SQLITE_CHANGESET_DATA] as the second argument.
+**
+**   If no row with matching primary key values is found in the database,
+**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+**   passed as the second argument.
+**
+**   If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
+**   (which can only happen if a foreign key constraint is violated), the
+**   conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
+**   passed as the second argument. This includes the case where the DELETE
+**   operation is attempted because an earlier call to the conflict handler
+**   function returned [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>INSERT Changes<dd>
+**   For each INSERT change, an attempt is made to insert the new row into
+**   the database.
+**
+**   If the attempt to insert the row fails because the database already 
+**   contains a row with the same primary key values, the conflict handler
+**   function is invoked with the second argument set to 
+**   [SQLITE_CHANGESET_CONFLICT].
+**
+**   If the attempt to insert the row fails because of some other constraint
+**   violation (e.g. NOT NULL or UNIQUE), the conflict handler function is 
+**   invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
+**   This includes the case where the INSERT operation is re-attempted because 
+**   an earlier call to the conflict handler function returned 
+**   [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>UPDATE Changes<dd>
+**   For each UPDATE change, this function checks if the target database 
+**   contains a row with the same primary key value (or values) as the 
+**   original row values stored in the changeset. If it does, and the values 
+**   stored in all non-primary key columns also match the values stored in 
+**   the changeset the row is updated within the target database.
+**
+**   If a row with matching primary key values is found, but one or more of
+**   the non-primary key fields contains a value different from an original
+**   row value stored in the changeset, the conflict-handler function is
+**   invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
+**   UPDATE changes only contain values for non-primary key fields that are
+**   to be modified, only those fields need to match the original values to
+**   avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
+**
+**   If no row with matching primary key values is found in the database,
+**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+**   passed as the second argument.
+**
+**   If the UPDATE operation is attempted, but SQLite returns 
+**   SQLITE_CONSTRAINT, the conflict-handler function is invoked with 
+**   [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
+**   This includes the case where the UPDATE operation is attempted after 
+**   an earlier call to the conflict handler function returned
+**   [SQLITE_CHANGESET_REPLACE].  
+** </dl>
+**
+** It is safe to execute SQL statements, including those that write to the
+** table that the callback related to, from within the xConflict callback.
+** This can be used to further customize the applications conflict
+** resolution strategy.
+**
+** All changes made by this function are enclosed in a savepoint transaction.
+** If any other error (aside from a constraint failure when attempting to
+** write to the target database) occurs, then the savepoint transaction is
+** rolled back, restoring the target database to its original state, and an 
+** SQLite error code returned.
+*/
+int sqlite3changeset_apply(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int nChangeset,                 /* Size of changeset in bytes */
+  void *pChangeset,               /* Changeset blob */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+);
+
+/* 
+** CAPI3REF: Constants Passed To The Conflict Handler
+**
+** Values that may be passed as the second argument to a conflict-handler.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_DATA<dd>
+**   The conflict handler is invoked with CHANGESET_DATA as the second argument
+**   when processing a DELETE or UPDATE change if a row with the required
+**   PRIMARY KEY fields is present in the database, but one or more other 
+**   (non primary-key) fields modified by the update do not contain the 
+**   expected "before" values.
+** 
+**   The conflicting row, in this case, is the database row with the matching
+**   primary key.
+** 
+** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
+**   The conflict handler is invoked with CHANGESET_NOTFOUND as the second
+**   argument when processing a DELETE or UPDATE change if a row with the
+**   required PRIMARY KEY fields is not present in the database.
+** 
+**   There is no conflicting row in this case. The results of invoking the
+**   sqlite3changeset_conflict() API are undefined.
+** 
+** <dt>SQLITE_CHANGESET_CONFLICT<dd>
+**   CHANGESET_CONFLICT is passed as the second argument to the conflict
+**   handler while processing an INSERT change if the operation would result 
+**   in duplicate primary key values.
+** 
+**   The conflicting row in this case is the database row with the matching
+**   primary key.
+**
+** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
+**   If foreign key handling is enabled, and applying a changeset leaves the
+**   database in a state containing foreign key violations, the conflict 
+**   handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
+**   exactly once before the changeset is committed. If the conflict handler
+**   returns CHANGESET_OMIT, the changes, including those that caused the
+**   foreign key constraint violation, are committed. Or, if it returns
+**   CHANGESET_ABORT, the changeset is rolled back.
+**
+**   No current or conflicting row information is provided. The only function
+**   it is possible to call on the supplied sqlite3_changeset_iter handle
+**   is sqlite3changeset_fk_conflicts().
+** 
+** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
+**   If any other constraint violation occurs while applying a change (i.e. 
+**   a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is 
+**   invoked with CHANGESET_CONSTRAINT as the second argument.
+** 
+**   There is no conflicting row in this case. The results of invoking the
+**   sqlite3changeset_conflict() API are undefined.
+**
+** </dl>
+*/
+#define SQLITE_CHANGESET_DATA        1
+#define SQLITE_CHANGESET_NOTFOUND    2
+#define SQLITE_CHANGESET_CONFLICT    3
+#define SQLITE_CHANGESET_CONSTRAINT  4
+#define SQLITE_CHANGESET_FOREIGN_KEY 5
+
+/* 
+** CAPI3REF: Constants Returned By The Conflict Handler
+**
+** A conflict handler callback must return one of the following three values.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_OMIT<dd>
+**   If a conflict handler returns this value no special action is taken. The
+**   change that caused the conflict is not applied. The session module 
+**   continues to the next change in the changeset.
+**
+** <dt>SQLITE_CHANGESET_REPLACE<dd>
+**   This value may only be returned if the second argument to the conflict
+**   handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
+**   is not the case, any changes applied so far are rolled back and the 
+**   call to sqlite3changeset_apply() returns SQLITE_MISUSE.
+**
+**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
+**   handler, then the conflicting row is either updated or deleted, depending
+**   on the type of change.
+**
+**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
+**   handler, then the conflicting row is removed from the database and a
+**   second attempt to apply the change is made. If this second attempt fails,
+**   the original row is restored to the database before continuing.
+**
+** <dt>SQLITE_CHANGESET_ABORT<dd>
+**   If this value is returned, any changes applied so far are rolled back 
+**   and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
+** </dl>
+*/
+#define SQLITE_CHANGESET_OMIT       0
+#define SQLITE_CHANGESET_REPLACE    1
+#define SQLITE_CHANGESET_ABORT      2
+
+/*
+** CAPI3REF: Streaming Versions of API functions.
+**
+** The six streaming API xxx_strm() functions serve similar purposes to the 
+** corresponding non-streaming API functions:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+**   <tr><th>Streaming function<th>Non-streaming equivalent</th>
+**   <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] 
+**   <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] 
+**   <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] 
+**   <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] 
+**   <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] 
+**   <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] 
+** </table>
+**
+** Non-streaming functions that accept changesets (or patchsets) as input
+** require that the entire changeset be stored in a single buffer in memory. 
+** Similarly, those that return a changeset or patchset do so by returning 
+** a pointer to a single large buffer allocated using sqlite3_malloc(). 
+** Normally this is convenient. However, if an application running in a 
+** low-memory environment is required to handle very large changesets, the
+** large contiguous memory allocations required can become onerous.
+**
+** In order to avoid this problem, instead of a single large buffer, input
+** is passed to a streaming API functions by way of a callback function that
+** the sessions module invokes to incrementally request input data as it is
+** required. In all cases, a pair of API function parameters such as
+**
+**  <pre>
+**  &nbsp;     int nChangeset,
+**  &nbsp;     void *pChangeset,
+**  </pre>
+**
+** Is replaced by:
+**
+**  <pre>
+**  &nbsp;     int (*xInput)(void *pIn, void *pData, int *pnData),
+**  &nbsp;     void *pIn,
+**  </pre>
+**
+** Each time the xInput callback is invoked by the sessions module, the first
+** argument passed is a copy of the supplied pIn context pointer. The second 
+** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no 
+** error occurs the xInput method should copy up to (*pnData) bytes of data 
+** into the buffer and set (*pnData) to the actual number of bytes copied 
+** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) 
+** should be set to zero to indicate this. Or, if an error occurs, an SQLite 
+** error code should be returned. In all cases, if an xInput callback returns
+** an error, all processing is abandoned and the streaming API function
+** returns a copy of the error code to the caller.
+**
+** In the case of sqlite3changeset_start_strm(), the xInput callback may be
+** invoked by the sessions module at any point during the lifetime of the
+** iterator. If such an xInput callback returns an error, the iterator enters
+** an error state, whereby all subsequent calls to iterator functions 
+** immediately fail with the same error code as returned by xInput.
+**
+** Similarly, streaming API functions that return changesets (or patchsets)
+** return them in chunks by way of a callback function instead of via a
+** pointer to a single large buffer. In this case, a pair of parameters such
+** as:
+**
+**  <pre>
+**  &nbsp;     int *pnChangeset,
+**  &nbsp;     void **ppChangeset,
+**  </pre>
+**
+** Is replaced by:
+**
+**  <pre>
+**  &nbsp;     int (*xOutput)(void *pOut, const void *pData, int nData),
+**  &nbsp;     void *pOut
+**  </pre>
+**
+** The xOutput callback is invoked zero or more times to return data to
+** the application. The first parameter passed to each call is a copy of the
+** pOut pointer supplied by the application. The second parameter, pData,
+** points to a buffer nData bytes in size containing the chunk of output
+** data being returned. If the xOutput callback successfully processes the
+** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
+** it should return some other SQLite error code. In this case processing
+** is immediately abandoned and the streaming API function returns a copy
+** of the xOutput error code to the application.
+**
+** The sessions module never invokes an xOutput callback with the third 
+** parameter set to a value less than or equal to zero. Other than this,
+** no guarantees are made as to the size of the chunks of data returned.
+*/
+int sqlite3changeset_apply_strm(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+  void *pIn,                                          /* First arg for xInput */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+);
+int sqlite3changeset_concat_strm(
+  int (*xInputA)(void *pIn, void *pData, int *pnData),
+  void *pInA,
+  int (*xInputB)(void *pIn, void *pData, int *pnData),
+  void *pInB,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3changeset_invert_strm(
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3changeset_start_strm(
+  sqlite3_changeset_iter **pp,
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn
+);
+int sqlite3session_changeset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3session_patchset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3changegroup_add_strm(sqlite3_changegroup*, 
+    int (*xInput)(void *pIn, void *pData, int *pnData),
+    void *pIn
+);
+int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+    int (*xOutput)(void *pOut, const void *pData, int nData), 
+    void *pOut
+);
+
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#if 0
+}
+#endif
+
+#endif  /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
+
+/******** End of sqlite3session.h *********/
+/******** Begin file fts5.h *********/
 /*
 ** 2014 May 31
 **
@@ -8485,11 +10018,13 @@ struct Fts5PhraseIter {
 **       ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
 **
 **   with $p set to a phrase equivalent to the phrase iPhrase of the
-**   current query is executed. For each row visited, the callback function
-**   passed as the fourth argument is invoked. The context and API objects 
-**   passed to the callback function may be used to access the properties of
-**   each matched row. Invoking Api.xUserData() returns a copy of the pointer
-**   passed as the third argument to pUserData.
+**   current query is executed. Any column filter that applies to
+**   phrase iPhrase of the current query is included in $p. For each 
+**   row visited, the callback function passed as the fourth argument 
+**   is invoked. The context and API objects passed to the callback 
+**   function may be used to access the properties of each matched row.
+**   Invoking Api.xUserData() returns a copy of the pointer passed as 
+**   the third argument to pUserData.
 **
 **   If the callback function returns any value other than SQLITE_OK, the
 **   query is abandoned and the xQueryPhrase function returns immediately.
@@ -8919,6 +10454,7 @@ struct fts5_api {
 #endif /* _FTS5_H */
 
 
+/******** End of fts5.h *********/
 
 /************** End of sqlite3.h *********************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
@@ -9036,13 +10572,13 @@ struct fts5_api {
 ** The suggested maximum number of in-memory pages to use for
 ** the main database table and for temporary tables.
 **
-** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
-** is 2000 pages.
+** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000,
+** which means the cache size is limited to 2048000 bytes of memory.
 ** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
 ** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
 */
 #ifndef SQLITE_DEFAULT_CACHE_SIZE
-# define SQLITE_DEFAULT_CACHE_SIZE  2000
+# define SQLITE_DEFAULT_CACHE_SIZE  -2000
 #endif
 
 /*
@@ -9055,8 +10591,9 @@ struct fts5_api {
 
 /*
 ** The maximum number of attached databases.  This must be between 0
-** and 62.  The upper bound on 62 is because a 64-bit integer bitmap
-** is used internally to track attached databases.
+** and 125.  The upper bound of 125 is because the attached databases are
+** counted using a signed 8-bit integer which has a maximum value of 127
+** and we have to allow 2 extra counts for the "main" and "temp" databases.
 */
 #ifndef SQLITE_MAX_ATTACHED
 # define SQLITE_MAX_ATTACHED 10
@@ -9091,7 +10628,7 @@ struct fts5_api {
 ** The default size of a database page.
 */
 #ifndef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE 1024
+# define SQLITE_DEFAULT_PAGE_SIZE 4096
 #endif
 #if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
 # undef SQLITE_DEFAULT_PAGE_SIZE
@@ -9179,7 +10716,7 @@ struct fts5_api {
 ** to the next, so we have developed the following set of #if statements
 ** to generate appropriate macros for a wide range of compilers.
 **
-** The correct "ANSI" way to do this is to use the intptr_t type. 
+** The correct "ANSI" way to do this is to use the intptr_t type.
 ** Unfortunately, that typedef is not available on all compilers, or
 ** if it is available, it requires an #include of specific headers
 ** that vary from one machine to the next.
@@ -9204,21 +10741,6 @@ struct fts5_api {
 #endif
 
 /*
-** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
-** something between S (inclusive) and E (exclusive).
-**
-** In other words, S is a buffer and E is a pointer to the first byte after
-** the end of buffer S.  This macro returns true if P points to something
-** contained within the buffer S.
-*/
-#if defined(HAVE_STDINT_H)
-# define SQLITE_WITHIN(P,S,E) \
-    ((uintptr_t)(P)>=(uintptr_t)(S) && (uintptr_t)(P)<(uintptr_t)(E))
-#else
-# define SQLITE_WITHIN(P,S,E) ((P)>=(S) && (P)<(E))
-#endif
-
-/*
 ** A macro to hint to the compiler that a function should not be
 ** inlined.
 */
@@ -9346,7 +10868,7 @@ struct fts5_api {
 ** is set.  Thus NDEBUG becomes an opt-in rather than an opt-out
 ** feature.
 */
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
 # define NDEBUG 1
 #endif
 #if defined(NDEBUG) && defined(SQLITE_DEBUG)
@@ -9361,7 +10883,7 @@ struct fts5_api {
 #endif
 
 /*
-** The testcase() macro is used to aid in coverage testing.  When 
+** The testcase() macro is used to aid in coverage testing.  When
 ** doing coverage testing, the condition inside the argument to
 ** testcase() must be evaluated both true and false in order to
 ** get full branch coverage.  The testcase() macro is inserted
@@ -9407,7 +10929,7 @@ SQLITE_PRIVATE   void sqlite3Coverage(int);
 #endif
 
 /*
-** The ALWAYS and NEVER macros surround boolean expressions which 
+** The ALWAYS and NEVER macros surround boolean expressions which
 ** are intended to always be true or false, respectively.  Such
 ** expressions could be omitted from the code completely.  But they
 ** are included in a few cases in order to enhance the resilience
@@ -9421,7 +10943,7 @@ SQLITE_PRIVATE   void sqlite3Coverage(int);
 ** be true and false so that the unreachable code they specify will
 ** not be counted as untested code.
 */
-#if defined(SQLITE_COVERAGE_TEST)
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
 # define ALWAYS(X)      (1)
 # define NEVER(X)       (0)
 #elif !defined(NDEBUG)
@@ -9474,6 +10996,13 @@ SQLITE_PRIVATE   void sqlite3Coverage(int);
 #endif
 
 /*
+** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN
+*/
+#ifdef SQLITE_OMIT_EXPLAIN
+# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
+#endif
+
+/*
 ** Return true (non-zero) if the input is an integer that is too large
 ** to fit in 32-bits.  This macro is used inside of various testcase()
 ** macros to verify that we have tested SQLite for large-file support.
@@ -9619,76 +11148,76 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 #define TK_AS                              24
 #define TK_WITHOUT                         25
 #define TK_COMMA                           26
-#define TK_ID                              27
-#define TK_INDEXED                         28
-#define TK_ABORT                           29
-#define TK_ACTION                          30
-#define TK_AFTER                           31
-#define TK_ANALYZE                         32
-#define TK_ASC                             33
-#define TK_ATTACH                          34
-#define TK_BEFORE                          35
-#define TK_BY                              36
-#define TK_CASCADE                         37
-#define TK_CAST                            38
-#define TK_COLUMNKW                        39
-#define TK_CONFLICT                        40
-#define TK_DATABASE                        41
-#define TK_DESC                            42
-#define TK_DETACH                          43
-#define TK_EACH                            44
-#define TK_FAIL                            45
-#define TK_FOR                             46
-#define TK_IGNORE                          47
-#define TK_INITIALLY                       48
-#define TK_INSTEAD                         49
-#define TK_LIKE_KW                         50
-#define TK_MATCH                           51
-#define TK_NO                              52
-#define TK_KEY                             53
-#define TK_OF                              54
-#define TK_OFFSET                          55
-#define TK_PRAGMA                          56
-#define TK_RAISE                           57
-#define TK_RECURSIVE                       58
-#define TK_REPLACE                         59
-#define TK_RESTRICT                        60
-#define TK_ROW                             61
-#define TK_TRIGGER                         62
-#define TK_VACUUM                          63
-#define TK_VIEW                            64
-#define TK_VIRTUAL                         65
-#define TK_WITH                            66
-#define TK_REINDEX                         67
-#define TK_RENAME                          68
-#define TK_CTIME_KW                        69
-#define TK_ANY                             70
-#define TK_OR                              71
-#define TK_AND                             72
-#define TK_IS                              73
-#define TK_BETWEEN                         74
-#define TK_IN                              75
-#define TK_ISNULL                          76
-#define TK_NOTNULL                         77
-#define TK_NE                              78
-#define TK_EQ                              79
-#define TK_GT                              80
-#define TK_LE                              81
-#define TK_LT                              82
-#define TK_GE                              83
-#define TK_ESCAPE                          84
-#define TK_BITAND                          85
-#define TK_BITOR                           86
-#define TK_LSHIFT                          87
-#define TK_RSHIFT                          88
-#define TK_PLUS                            89
-#define TK_MINUS                           90
-#define TK_STAR                            91
-#define TK_SLASH                           92
-#define TK_REM                             93
-#define TK_CONCAT                          94
-#define TK_COLLATE                         95
-#define TK_BITNOT                          96
+#define TK_OR                              27
+#define TK_AND                             28
+#define TK_IS                              29
+#define TK_MATCH                           30
+#define TK_LIKE_KW                         31
+#define TK_BETWEEN                         32
+#define TK_IN                              33
+#define TK_ISNULL                          34
+#define TK_NOTNULL                         35
+#define TK_NE                              36
+#define TK_EQ                              37
+#define TK_GT                              38
+#define TK_LE                              39
+#define TK_LT                              40
+#define TK_GE                              41
+#define TK_ESCAPE                          42
+#define TK_BITAND                          43
+#define TK_BITOR                           44
+#define TK_LSHIFT                          45
+#define TK_RSHIFT                          46
+#define TK_PLUS                            47
+#define TK_MINUS                           48
+#define TK_STAR                            49
+#define TK_SLASH                           50
+#define TK_REM                             51
+#define TK_CONCAT                          52
+#define TK_COLLATE                         53
+#define TK_BITNOT                          54
+#define TK_ID                              55
+#define TK_INDEXED                         56
+#define TK_ABORT                           57
+#define TK_ACTION                          58
+#define TK_AFTER                           59
+#define TK_ANALYZE                         60
+#define TK_ASC                             61
+#define TK_ATTACH                          62
+#define TK_BEFORE                          63
+#define TK_BY                              64
+#define TK_CASCADE                         65
+#define TK_CAST                            66
+#define TK_COLUMNKW                        67
+#define TK_CONFLICT                        68
+#define TK_DATABASE                        69
+#define TK_DESC                            70
+#define TK_DETACH                          71
+#define TK_EACH                            72
+#define TK_FAIL                            73
+#define TK_FOR                             74
+#define TK_IGNORE                          75
+#define TK_INITIALLY                       76
+#define TK_INSTEAD                         77
+#define TK_NO                              78
+#define TK_KEY                             79
+#define TK_OF                              80
+#define TK_OFFSET                          81
+#define TK_PRAGMA                          82
+#define TK_RAISE                           83
+#define TK_RECURSIVE                       84
+#define TK_REPLACE                         85
+#define TK_RESTRICT                        86
+#define TK_ROW                             87
+#define TK_TRIGGER                         88
+#define TK_VACUUM                          89
+#define TK_VIEW                            90
+#define TK_VIRTUAL                         91
+#define TK_WITH                            92
+#define TK_REINDEX                         93
+#define TK_RENAME                          94
+#define TK_CTIME_KW                        95
+#define TK_ANY                             96
 #define TK_STRING                          97
 #define TK_JOIN_KW                         98
 #define TK_CONSTRAINT                      99
@@ -9751,8 +11280,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 #define TK_UPLUS                          156
 #define TK_REGISTER                       157
 #define TK_ASTERISK                       158
-#define TK_SPACE                          159
-#define TK_ILLEGAL                        160
+#define TK_SPAN                           159
+#define TK_SPACE                          160
+#define TK_ILLEGAL                        161
 
 /* The token codes above must all fit in 8 bits */
 #define TKFLG_MASK           0xff  
@@ -9791,7 +11321,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 
 /*
 ** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
-** afterward. Having this macro allows us to cause the C compiler 
+** afterward. Having this macro allows us to cause the C compiler
 ** to omit code used by TEMP tables without messy #ifndef statements.
 */
 #ifdef SQLITE_OMIT_TEMPDB
@@ -9830,7 +11360,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 
 /*
 ** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
-** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it 
+** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
 ** to zero.
 */
 #if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0
@@ -9870,10 +11400,10 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 ** Macros to compute minimum and maximum of two numbers.
 */
 #ifndef MIN
-#define MIN(A,B) ((A)<(B)?(A):(B))
+# define MIN(A,B) ((A)<(B)?(A):(B))
 #endif
 #ifndef MAX
-#define MAX(A,B) ((A)>(B)?(A):(B))
+# define MAX(A,B) ((A)>(B)?(A):(B))
 #endif
 
 /*
@@ -9982,7 +11512,7 @@ typedef INT8_TYPE i8;              /* 1-byte signed integer */
 **      4 -> 20           1000 -> 99        1048576 -> 200
 **     10 -> 33           1024 -> 100    4294967296 -> 320
 **
-** The LogEst can be negative to indicate fractional values. 
+** The LogEst can be negative to indicate fractional values.
 ** Examples:
 **
 **    0.5 -> -10           0.1 -> -33        0.0625 -> -40
@@ -10003,6 +11533,27 @@ typedef INT16_TYPE LogEst;
 # endif
 #endif
 
+/* The uptr type is an unsigned integer large enough to hold a pointer
+*/
+#if defined(HAVE_STDINT_H)
+  typedef uintptr_t uptr;
+#elif SQLITE_PTRSIZE==4
+  typedef u32 uptr;
+#else
+  typedef u64 uptr;
+#endif
+
+/*
+** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
+** something between S (inclusive) and E (exclusive).
+**
+** In other words, S is a buffer and E is a pointer to the first byte after
+** the end of buffer S.  This macro returns true if P points to something
+** contained within the buffer S.
+*/
+#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
+
+
 /*
 ** Macros to determine whether the machine is big or little endian,
 ** and whether or not that determination is run-time or compile-time.
@@ -10048,7 +11599,7 @@ typedef INT16_TYPE LogEst;
 #define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
 #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
 
-/* 
+/*
 ** Round up a number to the next larger multiple of 8.  This is used
 ** to force 8-byte alignment on 64-bit architectures.
 */
@@ -10143,7 +11694,7 @@ typedef INT16_TYPE LogEst;
 
 /*
 ** An instance of the following structure is used to store the busy-handler
-** callback for a given sqlite handle. 
+** callback for a given sqlite handle.
 **
 ** The sqlite.busyHandler member of the sqlite struct contains the busy
 ** callback for the database handle. Each pager opened via the sqlite
@@ -10188,9 +11739,9 @@ struct BusyHandler {
 
 /*
 ** The following value as a destructor means to use sqlite3DbFree().
-** The sqlite3DbFree() routine requires two parameters instead of the 
-** one parameter that destructors normally want.  So we have to introduce 
-** this magic value that the code knows to handle differently.  Any 
+** The sqlite3DbFree() routine requires two parameters instead of the
+** one parameter that destructors normally want.  So we have to introduce
+** this magic value that the code knows to handle differently.  Any
 ** pointer will work here as long as it is distinct from SQLITE_STATIC
 ** and SQLITE_TRANSIENT.
 */
@@ -10217,16 +11768,16 @@ struct BusyHandler {
 SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J);
 SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L);
 #else
-  #define SQLITE_WSD 
+  #define SQLITE_WSD
   #define GLOBAL(t,v) v
   #define sqlite3GlobalConfig sqlite3Config
 #endif
 
 /*
 ** The following macros are used to suppress compiler warnings and to
-** make it clear to human readers when a function parameter is deliberately 
+** make it clear to human readers when a function parameter is deliberately
 ** left unused within the body of a function. This usually happens when
-** a function is called via a function pointer. For example the 
+** a function is called via a function pointer. For example the
 ** implementation of an SQL aggregate step callback may not use the
 ** parameter indicating the number of arguments passed to the aggregate,
 ** if it knows that this is enforced elsewhere.
@@ -10269,6 +11820,7 @@ typedef struct LookasideSlot LookasideSlot;
 typedef struct Module Module;
 typedef struct NameContext NameContext;
 typedef struct Parse Parse;
+typedef struct PreUpdate PreUpdate;
 typedef struct PrintfArguments PrintfArguments;
 typedef struct RowSet RowSet;
 typedef struct Savepoint Savepoint;
@@ -10292,7 +11844,7 @@ typedef struct WhereInfo WhereInfo;
 typedef struct With With;
 
 /*
-** Defer sourcing vdbe.h and btree.h until after the "u8" and 
+** Defer sourcing vdbe.h and btree.h until after the "u8" and
 ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
 ** pointer types (i.e. FuncDef) defined above.
 */
@@ -10368,7 +11920,6 @@ SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int);
 SQLITE_PRIVATE   int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
 #endif
 SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
 SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
@@ -10682,7 +12233,7 @@ typedef struct SubProgram SubProgram;
 struct VdbeOp {
   u8 opcode;          /* What operation to perform */
   signed char p4type; /* One of the P4_xxx constants for p4 */
-  u8 opflags;         /* Mask of the OPFLG_* flags in opcodes.h */
+  u8 notUsed1;
   u8 p5;              /* Fifth parameter is an unsigned character */
   int p1;             /* First operand */
   int p2;             /* Second parameter (often the jump destination) */
@@ -10701,6 +12252,7 @@ struct VdbeOp {
     KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
     int *ai;               /* Used when p4type is P4_INTARRAY */
     SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
+    Table *pTab;           /* Used when p4type is P4_TABLE */
 #ifdef SQLITE_ENABLE_CURSOR_HINTS
     Expr *pExpr;           /* Used when p4type is P4_EXPR */
 #endif
@@ -10765,7 +12317,8 @@ typedef struct VdbeOpList VdbeOpList;
 #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
 #define P4_SUBPROGRAM  (-18) /* P4 is a pointer to a SubProgram structure */
 #define P4_ADVANCE  (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
-#define P4_FUNCCTX  (-20) /* P4 is a pointer to an sqlite3_context object */
+#define P4_TABLE    (-20) /* P4 is a pointer to a Table structure */
+#define P4_FUNCCTX  (-21) /* P4 is a pointer to an sqlite3_context object */
 
 /* Error message codes for OP_Halt */
 #define P5_ConstraintNotNull 1
@@ -10823,153 +12376,152 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_VUpdate        12 /* synopsis: data=r[P3@P2]                    */
 #define OP_Goto           13
 #define OP_Gosub          14
-#define OP_Return         15
-#define OP_InitCoroutine  16
-#define OP_EndCoroutine   17
-#define OP_Yield          18
+#define OP_InitCoroutine  15
+#define OP_Yield          16
+#define OP_MustBeInt      17
+#define OP_Jump           18
 #define OP_Not            19 /* same as TK_NOT, synopsis: r[P2]= !r[P1]    */
-#define OP_HaltIfNull     20 /* synopsis: if r[P3]=null halt               */
-#define OP_Halt           21
-#define OP_Integer        22 /* synopsis: r[P2]=P1                         */
-#define OP_Int64          23 /* synopsis: r[P2]=P4                         */
-#define OP_String         24 /* synopsis: r[P2]='P4' (len=P1)              */
-#define OP_Null           25 /* synopsis: r[P2..P3]=NULL                   */
-#define OP_SoftNull       26 /* synopsis: r[P1]=NULL                       */
-#define OP_Blob           27 /* synopsis: r[P2]=P4 (len=P1)                */
-#define OP_Variable       28 /* synopsis: r[P2]=parameter(P1,P4)           */
-#define OP_Move           29 /* synopsis: r[P2@P3]=r[P1@P3]                */
-#define OP_Copy           30 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
-#define OP_SCopy          31 /* synopsis: r[P2]=r[P1]                      */
-#define OP_IntCopy        32 /* synopsis: r[P2]=r[P1]                      */
-#define OP_ResultRow      33 /* synopsis: output=r[P1@P2]                  */
-#define OP_CollSeq        34
-#define OP_Function0      35 /* synopsis: r[P3]=func(r[P2@P5])             */
-#define OP_Function       36 /* synopsis: r[P3]=func(r[P2@P5])             */
-#define OP_AddImm         37 /* synopsis: r[P1]=r[P1]+P2                   */
-#define OP_MustBeInt      38
-#define OP_RealAffinity   39
-#define OP_Cast           40 /* synopsis: affinity(r[P1])                  */
-#define OP_Permutation    41
-#define OP_Compare        42 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
-#define OP_Jump           43
-#define OP_Once           44
-#define OP_If             45
-#define OP_IfNot          46
-#define OP_Column         47 /* synopsis: r[P3]=PX                         */
-#define OP_Affinity       48 /* synopsis: affinity(r[P1@P2])               */
-#define OP_MakeRecord     49 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
-#define OP_Count          50 /* synopsis: r[P2]=count()                    */
-#define OP_ReadCookie     51
-#define OP_SetCookie      52
-#define OP_ReopenIdx      53 /* synopsis: root=P2 iDb=P3                   */
-#define OP_OpenRead       54 /* synopsis: root=P2 iDb=P3                   */
-#define OP_OpenWrite      55 /* synopsis: root=P2 iDb=P3                   */
-#define OP_OpenAutoindex  56 /* synopsis: nColumn=P2                       */
-#define OP_OpenEphemeral  57 /* synopsis: nColumn=P2                       */
-#define OP_SorterOpen     58
-#define OP_SequenceTest   59 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
-#define OP_OpenPseudo     60 /* synopsis: P3 columns in r[P2]              */
-#define OP_Close          61
-#define OP_ColumnsUsed    62
-#define OP_SeekLT         63 /* synopsis: key=r[P3@P4]                     */
-#define OP_SeekLE         64 /* synopsis: key=r[P3@P4]                     */
-#define OP_SeekGE         65 /* synopsis: key=r[P3@P4]                     */
-#define OP_SeekGT         66 /* synopsis: key=r[P3@P4]                     */
-#define OP_NoConflict     67 /* synopsis: key=r[P3@P4]                     */
-#define OP_NotFound       68 /* synopsis: key=r[P3@P4]                     */
-#define OP_Found          69 /* synopsis: key=r[P3@P4]                     */
-#define OP_NotExists      70 /* synopsis: intkey=r[P3]                     */
-#define OP_Or             71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
-#define OP_And            72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_Sequence       73 /* synopsis: r[P2]=cursor[P1].ctr++           */
-#define OP_NewRowid       74 /* synopsis: r[P2]=rowid                      */
-#define OP_Insert         75 /* synopsis: intkey=r[P3] data=r[P2]          */
-#define OP_IsNull         76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull        77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne             78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
-#define OP_Eq             79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
-#define OP_Gt             80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
-#define OP_Le             81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
-#define OP_Lt             82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
-#define OP_Ge             83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
-#define OP_InsertInt      84 /* synopsis: intkey=P3 data=r[P2]             */
-#define OP_BitAnd         85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr          86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft      87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
-#define OP_ShiftRight     88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
-#define OP_Add            89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract       90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply       91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide         92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder      93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat         94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_Delete         95
-#define OP_BitNot         96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_Once           20
+#define OP_If             21
+#define OP_IfNot          22
+#define OP_SeekLT         23 /* synopsis: key=r[P3@P4]                     */
+#define OP_SeekLE         24 /* synopsis: key=r[P3@P4]                     */
+#define OP_SeekGE         25 /* synopsis: key=r[P3@P4]                     */
+#define OP_SeekGT         26 /* synopsis: key=r[P3@P4]                     */
+#define OP_Or             27 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And            28 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_NoConflict     29 /* synopsis: key=r[P3@P4]                     */
+#define OP_NotFound       30 /* synopsis: key=r[P3@P4]                     */
+#define OP_Found          31 /* synopsis: key=r[P3@P4]                     */
+#define OP_NotExists      32 /* synopsis: intkey=r[P3]                     */
+#define OP_Last           33
+#define OP_IsNull         34 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull        35 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne             36 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
+#define OP_Eq             37 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
+#define OP_Gt             38 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
+#define OP_Le             39 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
+#define OP_Lt             40 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
+#define OP_Ge             41 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
+#define OP_SorterSort     42
+#define OP_BitAnd         43 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr          44 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft      45 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight     46 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add            47 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract       48 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply       49 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide         50 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder      51 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat         52 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_Sort           53
+#define OP_BitNot         54 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_Rewind         55
+#define OP_IdxLE          56 /* synopsis: key=r[P3@P4]                     */
+#define OP_IdxGT          57 /* synopsis: key=r[P3@P4]                     */
+#define OP_IdxLT          58 /* synopsis: key=r[P3@P4]                     */
+#define OP_IdxGE          59 /* synopsis: key=r[P3@P4]                     */
+#define OP_RowSetRead     60 /* synopsis: r[P3]=rowset(P1)                 */
+#define OP_RowSetTest     61 /* synopsis: if r[P3] in rowset(P1) goto P2   */
+#define OP_Program        62
+#define OP_FkIfZero       63 /* synopsis: if fkctr[P1]==0 goto P2          */
+#define OP_IfPos          64 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero      65 /* synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 */
+#define OP_DecrJumpZero   66 /* synopsis: if (--r[P1])==0 goto P2          */
+#define OP_IncrVacuum     67
+#define OP_VNext          68
+#define OP_Init           69 /* synopsis: Start at P2                      */
+#define OP_Return         70
+#define OP_EndCoroutine   71
+#define OP_HaltIfNull     72 /* synopsis: if r[P3]=null halt               */
+#define OP_Halt           73
+#define OP_Integer        74 /* synopsis: r[P2]=P1                         */
+#define OP_Int64          75 /* synopsis: r[P2]=P4                         */
+#define OP_String         76 /* synopsis: r[P2]='P4' (len=P1)              */
+#define OP_Null           77 /* synopsis: r[P2..P3]=NULL                   */
+#define OP_SoftNull       78 /* synopsis: r[P1]=NULL                       */
+#define OP_Blob           79 /* synopsis: r[P2]=P4 (len=P1)                */
+#define OP_Variable       80 /* synopsis: r[P2]=parameter(P1,P4)           */
+#define OP_Move           81 /* synopsis: r[P2@P3]=r[P1@P3]                */
+#define OP_Copy           82 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
+#define OP_SCopy          83 /* synopsis: r[P2]=r[P1]                      */
+#define OP_IntCopy        84 /* synopsis: r[P2]=r[P1]                      */
+#define OP_ResultRow      85 /* synopsis: output=r[P1@P2]                  */
+#define OP_CollSeq        86
+#define OP_Function0      87 /* synopsis: r[P3]=func(r[P2@P5])             */
+#define OP_Function       88 /* synopsis: r[P3]=func(r[P2@P5])             */
+#define OP_AddImm         89 /* synopsis: r[P1]=r[P1]+P2                   */
+#define OP_RealAffinity   90
+#define OP_Cast           91 /* synopsis: affinity(r[P1])                  */
+#define OP_Permutation    92
+#define OP_Compare        93 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
+#define OP_Column         94 /* synopsis: r[P3]=PX                         */
+#define OP_Affinity       95 /* synopsis: affinity(r[P1@P2])               */
+#define OP_MakeRecord     96 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
 #define OP_String8        97 /* same as TK_STRING, synopsis: r[P2]='P4'    */
-#define OP_ResetCount     98
-#define OP_SorterCompare  99 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData    100 /* synopsis: r[P2]=data                       */
-#define OP_RowKey        101 /* synopsis: r[P2]=key                        */
-#define OP_RowData       102 /* synopsis: r[P2]=data                       */
-#define OP_Rowid         103 /* synopsis: r[P2]=rowid                      */
-#define OP_NullRow       104
-#define OP_Last          105
-#define OP_SorterSort    106
-#define OP_Sort          107
-#define OP_Rewind        108
-#define OP_SorterInsert  109
-#define OP_IdxInsert     110 /* synopsis: key=r[P2]                        */
-#define OP_IdxDelete     111 /* synopsis: key=r[P2@P3]                     */
-#define OP_Seek          112 /* synopsis: Move P3 to P1.rowid              */
-#define OP_IdxRowid      113 /* synopsis: r[P2]=rowid                      */
-#define OP_IdxLE         114 /* synopsis: key=r[P3@P4]                     */
-#define OP_IdxGT         115 /* synopsis: key=r[P3@P4]                     */
-#define OP_IdxLT         116 /* synopsis: key=r[P3@P4]                     */
-#define OP_IdxGE         117 /* synopsis: key=r[P3@P4]                     */
-#define OP_Destroy       118
-#define OP_Clear         119
-#define OP_ResetSorter   120
-#define OP_CreateIndex   121 /* synopsis: r[P2]=root iDb=P1                */
-#define OP_CreateTable   122 /* synopsis: r[P2]=root iDb=P1                */
-#define OP_ParseSchema   123
-#define OP_LoadAnalysis  124
-#define OP_DropTable     125
-#define OP_DropIndex     126
-#define OP_DropTrigger   127
-#define OP_IntegrityCk   128
-#define OP_RowSetAdd     129 /* synopsis: rowset(P1)=r[P2]                 */
-#define OP_RowSetRead    130 /* synopsis: r[P3]=rowset(P1)                 */
-#define OP_RowSetTest    131 /* synopsis: if r[P3] in rowset(P1) goto P2   */
-#define OP_Program       132
+#define OP_Count          98 /* synopsis: r[P2]=count()                    */
+#define OP_ReadCookie     99
+#define OP_SetCookie     100
+#define OP_ReopenIdx     101 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenRead      102 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenWrite     103 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenAutoindex 104 /* synopsis: nColumn=P2                       */
+#define OP_OpenEphemeral 105 /* synopsis: nColumn=P2                       */
+#define OP_SorterOpen    106
+#define OP_SequenceTest  107 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
+#define OP_OpenPseudo    108 /* synopsis: P3 columns in r[P2]              */
+#define OP_Close         109
+#define OP_ColumnsUsed   110
+#define OP_Sequence      111 /* synopsis: r[P2]=cursor[P1].ctr++           */
+#define OP_NewRowid      112 /* synopsis: r[P2]=rowid                      */
+#define OP_Insert        113 /* synopsis: intkey=r[P3] data=r[P2]          */
+#define OP_InsertInt     114 /* synopsis: intkey=P3 data=r[P2]             */
+#define OP_Delete        115
+#define OP_ResetCount    116
+#define OP_SorterCompare 117 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData    118 /* synopsis: r[P2]=data                       */
+#define OP_RowKey        119 /* synopsis: r[P2]=key                        */
+#define OP_RowData       120 /* synopsis: r[P2]=data                       */
+#define OP_Rowid         121 /* synopsis: r[P2]=rowid                      */
+#define OP_NullRow       122
+#define OP_SorterInsert  123
+#define OP_IdxInsert     124 /* synopsis: key=r[P2]                        */
+#define OP_IdxDelete     125 /* synopsis: key=r[P2@P3]                     */
+#define OP_Seek          126 /* synopsis: Move P3 to P1.rowid              */
+#define OP_IdxRowid      127 /* synopsis: r[P2]=rowid                      */
+#define OP_Destroy       128
+#define OP_Clear         129
+#define OP_ResetSorter   130
+#define OP_CreateIndex   131 /* synopsis: r[P2]=root iDb=P1                */
+#define OP_CreateTable   132 /* synopsis: r[P2]=root iDb=P1                */
 #define OP_Real          133 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
-#define OP_Param         134
-#define OP_FkCounter     135 /* synopsis: fkctr[P1]+=P2                    */
-#define OP_FkIfZero      136 /* synopsis: if fkctr[P1]==0 goto P2          */
-#define OP_MemMax        137 /* synopsis: r[P1]=max(r[P1],r[P2])           */
-#define OP_IfPos         138 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_OffsetLimit   139 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-#define OP_IfNotZero     140 /* synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 */
-#define OP_DecrJumpZero  141 /* synopsis: if (--r[P1])==0 goto P2          */
-#define OP_JumpZeroIncr  142 /* synopsis: if (r[P1]++)==0 ) goto P2        */
-#define OP_AggStep0      143 /* synopsis: accum=r[P3] step(r[P2@P5])       */
-#define OP_AggStep       144 /* synopsis: accum=r[P3] step(r[P2@P5])       */
-#define OP_AggFinal      145 /* synopsis: accum=r[P1] N=P2                 */
-#define OP_IncrVacuum    146
-#define OP_Expire        147
-#define OP_TableLock     148 /* synopsis: iDb=P1 root=P2 write=P3          */
-#define OP_VBegin        149
-#define OP_VCreate       150
-#define OP_VDestroy      151
-#define OP_VOpen         152
-#define OP_VColumn       153 /* synopsis: r[P3]=vcolumn(P2)                */
-#define OP_VNext         154
+#define OP_ParseSchema   134
+#define OP_LoadAnalysis  135
+#define OP_DropTable     136
+#define OP_DropIndex     137
+#define OP_DropTrigger   138
+#define OP_IntegrityCk   139
+#define OP_RowSetAdd     140 /* synopsis: rowset(P1)=r[P2]                 */
+#define OP_Param         141
+#define OP_FkCounter     142 /* synopsis: fkctr[P1]+=P2                    */
+#define OP_MemMax        143 /* synopsis: r[P1]=max(r[P1],r[P2])           */
+#define OP_OffsetLimit   144 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggStep0      145 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+#define OP_AggStep       146 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+#define OP_AggFinal      147 /* synopsis: accum=r[P1] N=P2                 */
+#define OP_Expire        148
+#define OP_TableLock     149 /* synopsis: iDb=P1 root=P2 write=P3          */
+#define OP_VBegin        150
+#define OP_VCreate       151
+#define OP_VDestroy      152
+#define OP_VOpen         153
+#define OP_VColumn       154 /* synopsis: r[P3]=vcolumn(P2)                */
 #define OP_VRename       155
 #define OP_Pagecount     156
 #define OP_MaxPgcnt      157
-#define OP_Init          158 /* synopsis: Start at P2                      */
-#define OP_CursorHint    159
-#define OP_Noop          160
-#define OP_Explain       161
+#define OP_CursorHint    158
+#define OP_Noop          159
+#define OP_Explain       160
 
 /* Properties such as "out2" or "jump" that are specified in
 ** comments following the "case" for each opcode in the vdbe.c
@@ -10983,26 +12535,34 @@ typedef struct VdbeOpList VdbeOpList;
 #define OPFLG_OUT3        0x20  /* out3:  P3 is an output */
 #define OPFLG_INITIALIZER {\
 /*   0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\
-/*   8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x02,\
-/*  16 */ 0x01, 0x02, 0x03, 0x12, 0x08, 0x00, 0x10, 0x10,\
-/*  24 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
-/*  32 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02,\
-/*  40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\
-/*  48 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
-/*  56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,\
-/*  64 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x26,\
-/*  72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\
-/*  80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\
-/*  88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\
-/*  96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
-/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\
-/* 112 */ 0x00, 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00,\
-/* 120 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 128 */ 0x00, 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00,\
-/* 136 */ 0x01, 0x04, 0x03, 0x1a, 0x03, 0x03, 0x03, 0x00,\
-/* 144 */ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 152 */ 0x00, 0x00, 0x01, 0x00, 0x10, 0x10, 0x01, 0x00,\
-/* 160 */ 0x00, 0x00,}
+/*   8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\
+/*  16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x09,\
+/*  24 */ 0x09, 0x09, 0x09, 0x26, 0x26, 0x09, 0x09, 0x09,\
+/*  32 */ 0x09, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
+/*  40 */ 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26, 0x26,\
+/*  48 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x01, 0x12, 0x01,\
+/*  56 */ 0x01, 0x01, 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01,\
+/*  64 */ 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x02, 0x02,\
+/*  72 */ 0x08, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10,\
+/*  80 */ 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\
+/*  88 */ 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,\
+/*  96 */ 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
+/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+/* 112 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 120 */ 0x00, 0x10, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\
+/* 128 */ 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00,\
+/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
+/* 144 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 160 */ 0x00,}
+
+/* The sqlite3P2Values() routine is able to run faster if it knows
+** the value of the largest JUMP opcode.  The smaller the maximum
+** JUMP opcode the better, so the mkopcodeh.tcl script that
+** generated this include file strives to group all JUMP opcodes
+** together near the beginning of the list.
+*/
+#define SQLITE_MX_JUMP_OPCODE  69  /* Maximum JUMP opcode */
 
 /************** End of opcodes.h *********************************************/
 /************** Continuing where we left off in vdbe.h ***********************/
@@ -11044,6 +12604,7 @@ SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
 SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
 SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
+SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
@@ -11224,7 +12785,11 @@ typedef struct PgHdr DbPage;
 #define PAGER_LOCKINGMODE_EXCLUSIVE   1
 
 /*
-** Numeric constants that encode the journalmode.  
+** Numeric constants that encode the journalmode.
+**
+** The numeric values encoded here (other than PAGER_JOURNALMODE_QUERY)
+** are exposed in the API via the "PRAGMA journal_mode" command and
+** therefore cannot be changed without a compatibility break.
 */
 #define PAGER_JOURNALMODE_QUERY     (-1)  /* Query the value of journalmode */
 #define PAGER_JOURNALMODE_DELETE      0   /* Commit by deleting journal file */
@@ -11242,6 +12807,11 @@ typedef struct PgHdr DbPage;
 
 /*
 ** Flags for sqlite3PagerSetFlags()
+**
+** Value constraints (enforced via assert()):
+**    PAGER_FULLFSYNC      == SQLITE_FullFSync
+**    PAGER_CKPT_FULLFSYNC == SQLITE_CkptFullFSync
+**    PAGER_CACHE_SPILL    == SQLITE_CacheSpill
 */
 #define PAGER_SYNCHRONOUS_OFF       0x01  /* PRAGMA synchronous=OFF */
 #define PAGER_SYNCHRONOUS_NORMAL    0x02  /* PRAGMA synchronous=NORMAL */
@@ -11347,7 +12917,6 @@ SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*);
 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
 SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*);
 SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
-SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
@@ -11412,7 +12981,7 @@ struct PgHdr {
   sqlite3_pcache_page *pPage;    /* Pcache object page handle */
   void *pData;                   /* Page data */
   void *pExtra;                  /* Extra content */
-  PgHdr *pDirty;                 /* Transient list of dirty pages */
+  PgHdr *pDirty;                 /* Transient list of dirty sorted by pgno */
   Pager *pPager;                 /* The pager this page is part of */
   Pgno pgno;                     /* Page number for this page */
 #ifdef SQLITE_CHECK_PAGES
@@ -11437,11 +13006,10 @@ struct PgHdr {
 #define PGHDR_WRITEABLE       0x004  /* Journaled and ready to modify */
 #define PGHDR_NEED_SYNC       0x008  /* Fsync the rollback journal before
                                      ** writing this page to the database */
-#define PGHDR_NEED_READ       0x010  /* Content is unread */
-#define PGHDR_DONT_WRITE      0x020  /* Do not write content to disk */
-#define PGHDR_MMAP            0x040  /* This is an mmap page object */
+#define PGHDR_DONT_WRITE      0x010  /* Do not write content to disk */
+#define PGHDR_MMAP            0x020  /* This is an mmap page object */
 
-#define PGHDR_WAL_APPEND      0x080  /* Appended to wal file */
+#define PGHDR_WAL_APPEND      0x040  /* Appended to wal file */
 
 /* Initialize and shutdown the page cache subsystem */
 SQLITE_PRIVATE int sqlite3PcacheInitialize(void);
@@ -11485,6 +13053,7 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*);         /* Remove page from cache
 SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*);    /* Make sure page is marked dirty */
 SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*);    /* Mark a single page as clean */
 SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*);    /* Mark all dirty list pages as clean */
+SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache*);
 
 /* Change a page number.  Used by incr-vacuum. */
 SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno);
@@ -11523,6 +13092,11 @@ SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*);
 SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *));
 #endif
 
+#if defined(SQLITE_DEBUG)
+/* Check invariants on a PgHdr object */
+SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr*);
+#endif
+
 /* Set and get the suggested cache-size for the specified pager-cache.
 **
 ** If no global maximum is configured, then the system attempts to limit
@@ -11559,11 +13133,13 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
 SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
 
+/* Number of dirty pages as a percentage of the configured cache size */
+SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
+
 #endif /* _PCACHE_H_ */
 
 /************** End of pcache.h **********************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
-
 /************** Include os.h in the middle of sqliteInt.h ********************/
 /************** Begin file os.h **********************************************/
 /*
@@ -11789,7 +13365,7 @@ SQLITE_PRIVATE int sqlite3OsInit(void);
 /* 
 ** Functions for accessing sqlite3_file methods 
 */
-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*);
+SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*);
 SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
 SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
 SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size);
@@ -11826,6 +13402,7 @@ SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
 SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
 SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
+SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*);
 SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
 
 /*
@@ -11833,7 +13410,7 @@ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
 ** sqlite3_malloc() to obtain space for the file-handle structure.
 */
 SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
+SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *);
 
 #endif /* _SQLITE_OS_H_ */
 
@@ -11915,6 +13492,36 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 /************** End of mutex.h ***********************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
 
+/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
+** synchronous setting to EXTRA.  It is no longer supported.
+*/
+#ifdef SQLITE_EXTRA_DURABLE
+# warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE
+# define SQLITE_DEFAULT_SYNCHRONOUS 3
+#endif
+
+/*
+** Default synchronous levels.
+**
+** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ
+** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1.
+**
+**           PAGER_SYNCHRONOUS       DEFAULT_SYNCHRONOUS
+**   OFF           1                         0
+**   NORMAL        2                         1
+**   FULL          3                         2
+**   EXTRA         4                         3
+**
+** The "PRAGMA synchronous" statement also uses the zero-based numbers.
+** In other words, the zero-based numbers are used for all external interfaces
+** and the one-based values are used internally.
+*/
+#ifndef SQLITE_DEFAULT_SYNCHRONOUS
+# define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1)
+#endif
+#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS
+# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS
+#endif
 
 /*
 ** Each database file to be accessed by the system is an instance
@@ -11924,9 +13531,10 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 ** databases may be attached.
 */
 struct Db {
-  char *zName;         /* Name of this database */
+  const char *zName;   /* Name of this database */
   Btree *pBt;          /* The B*Tree structure for this database file */
   u8 safety_level;     /* How aggressive at syncing data to disk */
+  u8 bSyncSet;         /* True if "PRAGMA synchronous=N" has been run */
   Schema *pSchema;     /* Pointer to database schema (possibly shared) */
 };
 
@@ -11937,7 +13545,7 @@ struct Db {
 ** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing.
 ** In shared cache mode, a single Schema object can be shared by multiple
 ** Btrees that refer to the same underlying BtShared object.
-** 
+**
 ** Schema objects are automatically deallocated when the last Btree that
 ** references them is destroyed.   The TEMP Schema is manually freed by
 ** sqlite3_close().
@@ -11962,7 +13570,7 @@ struct Schema {
 };
 
 /*
-** These macros can be used to test, set, or clear bits in the 
+** These macros can be used to test, set, or clear bits in the
 ** Db.pSchema->flags field.
 */
 #define DbHasProperty(D,I,P)     (((D)->aDb[I].pSchema->schemaFlags&(P))==(P))
@@ -12026,13 +13634,15 @@ struct LookasideSlot {
 };
 
 /*
-** A hash table for function definitions.
+** A hash table for built-in function definitions.  (Application-defined
+** functions use a regular table table from hash.h.)
 **
 ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
-** Collisions are on the FuncDef.pHash chain.
+** Collisions are on the FuncDef.u.pHash chain.
 */
+#define SQLITE_FUNC_HASH_SZ 23
 struct FuncDefHash {
-  FuncDef *a[23];       /* Hash table for functions */
+  FuncDef *a[SQLITE_FUNC_HASH_SZ];       /* Hash table for functions */
 };
 
 #ifdef SQLITE_USER_AUTHENTICATION
@@ -12090,6 +13700,7 @@ struct sqlite3 {
   unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
   int errCode;                  /* Most recent error code (SQLITE_*) */
   int errMask;                  /* & result codes with this before returning */
+  int iSysErrno;                /* Errno value from last system error */
   u16 dbOptFlags;               /* Flags to enable/disable optimizations */
   u8 enc;                       /* Text encoding */
   u8 autoCommit;                /* The auto-commit flag. */
@@ -12125,12 +13736,19 @@ struct sqlite3 {
   void *pTraceArg;                          /* Argument to the trace function */
   void (*xProfile)(void*,const char*,u64);  /* Profiling function */
   void *pProfileArg;                        /* Argument to profile function */
-  void *pCommitArg;                 /* Argument to xCommitCallback() */   
+  void *pCommitArg;                 /* Argument to xCommitCallback() */
   int (*xCommitCallback)(void*);    /* Invoked at every commit. */
-  void *pRollbackArg;               /* Argument to xRollbackCallback() */   
+  void *pRollbackArg;               /* Argument to xRollbackCallback() */
   void (*xRollbackCallback)(void*); /* Invoked at every commit. */
   void *pUpdateArg;
   void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+  void *pPreUpdateArg;          /* First argument to xPreUpdateCallback */
+  void (*xPreUpdateCallback)(   /* Registered using sqlite3_preupdate_hook() */
+    void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
+  );
+  PreUpdate *pPreUpdate;        /* Context for active pre-update callback */
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 #ifndef SQLITE_OMIT_WAL
   int (*xWalCallback)(void *, sqlite3 *, const char *, int);
   void *pWalArg;
@@ -12160,7 +13778,7 @@ struct sqlite3 {
   VTable **aVTrans;             /* Virtual tables with open transactions */
   VTable *pDisconnect;    /* Disconnect these in next sqlite3_prepare() */
 #endif
-  FuncDefHash aFunc;            /* Hash table of connection functions */
+  Hash aFunc;                   /* Hash table of connection functions */
   Hash aCollSeq;                /* All collating sequences */
   BusyHandler busyHandler;      /* Busy callback */
   Db aDbStatic[2];              /* Static space for the 2 default backends */
@@ -12172,8 +13790,8 @@ struct sqlite3 {
   i64 nDeferredImmCons;         /* Net deferred immediate constraints */
   size_t *pnBytesFreed;         /* If not NULL, increment this in DbFree() */
 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
-  /* The following variables are all protected by the STATIC_MASTER 
-  ** mutex, not by sqlite3.mutex. They are used by code in notify.c. 
+  /* The following variables are all protected by the STATIC_MASTER
+  ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
   **
   ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
   ** unlock so that it can proceed.
@@ -12201,6 +13819,11 @@ struct sqlite3 {
 
 /*
 ** Possible values for the sqlite3.flags.
+**
+** Value constraints (enforced via assert()):
+**      SQLITE_FullFSync     == PAGER_FULLFSYNC
+**      SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
+**      SQLITE_CacheSpill    == PAGER_CACHE_SPILL
 */
 #define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
 #define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */
@@ -12228,12 +13851,14 @@ struct sqlite3 {
 #define SQLITE_AutoIndex      0x00100000  /* Enable automatic indexes */
 #define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
 #define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
-#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
-#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
-#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
-#define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */
-#define SQLITE_Vacuum         0x08000000  /* Currently in a VACUUM */
-#define SQLITE_CellSizeCk     0x10000000  /* Check btree cell sizes on load */
+#define SQLITE_LoadExtFunc    0x00800000  /* Enable load_extension() SQL func */
+#define SQLITE_EnableTrigger  0x01000000  /* True to enable triggers */
+#define SQLITE_DeferFKs       0x02000000  /* Defer all FK constraints */
+#define SQLITE_QueryOnly      0x04000000  /* Disable database changes */
+#define SQLITE_VdbeEQP        0x08000000  /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_Vacuum         0x10000000  /* Currently in a VACUUM */
+#define SQLITE_CellSizeCk     0x20000000  /* Check btree cell sizes on load */
+#define SQLITE_Fts3Tokenizer  0x40000000  /* Enable fts3_tokenizer(2) */
 
 
 /*
@@ -12287,27 +13912,33 @@ struct sqlite3 {
 
 /*
 ** Each SQL function is defined by an instance of the following
-** structure.  A pointer to this structure is stored in the sqlite.aFunc
-** hash table.  When multiple functions have the same name, the hash table
-** points to a linked list of these structures.
+** structure.  For global built-in functions (ex: substr(), max(), count())
+** a pointer to this structure is held in the sqlite3BuiltinFunctions object.
+** For per-connection application-defined functions, a pointer to this
+** structure is held in the db->aHash hash table.
+**
+** The u.pHash field is used by the global built-ins.  The u.pDestructor
+** field is used by per-connection app-def functions.
 */
 struct FuncDef {
-  i16 nArg;            /* Number of arguments.  -1 means unlimited */
+  i8 nArg;             /* Number of arguments.  -1 means unlimited */
   u16 funcFlags;       /* Some combination of SQLITE_FUNC_* */
   void *pUserData;     /* User data parameter */
   FuncDef *pNext;      /* Next function with same name */
   void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
   void (*xFinalize)(sqlite3_context*);                  /* Agg finalizer */
-  char *zName;         /* SQL name of the function. */
-  FuncDef *pHash;      /* Next with a different name but the same hash */
-  FuncDestructor *pDestructor;   /* Reference counted destructor function */
+  const char *zName;   /* SQL name of the function. */
+  union {
+    FuncDef *pHash;      /* Next with a different name but the same hash */
+    FuncDestructor *pDestructor;   /* Reference counted destructor function */
+  } u;
 };
 
 /*
 ** This structure encapsulates a user-function destructor callback (as
 ** configured using create_function_v2()) and a reference counter. When
 ** create_function_v2() is called to create a function with a destructor,
-** a single object of this type is allocated. FuncDestructor.nRef is set to 
+** a single object of this type is allocated. FuncDestructor.nRef is set to
 ** the number of FuncDef objects created (either 1 or 3, depending on whether
 ** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor
 ** member of each of the new FuncDef objects is set to point to the allocated
@@ -12328,6 +13959,13 @@ struct FuncDestructor {
 ** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG.  And
 ** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC.  There
 ** are assert() statements in the code to verify this.
+**
+** Value constraints (enforced via assert()):
+**     SQLITE_FUNC_MINMAX    ==  NC_MinMaxAgg      == SF_MinMaxAgg
+**     SQLITE_FUNC_LENGTH    ==  OPFLAG_LENGTHARG
+**     SQLITE_FUNC_TYPEOF    ==  OPFLAG_TYPEOFARG
+**     SQLITE_FUNC_CONSTANT  ==  SQLITE_DETERMINISTIC from the API
+**     SQLITE_FUNC_ENCMASK   depends on SQLITE_UTF* macros in the API
 */
 #define SQLITE_FUNC_ENCMASK  0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
 #define SQLITE_FUNC_LIKE     0x0004 /* Candidate for the LIKE optimization */
@@ -12349,10 +13987,10 @@ struct FuncDestructor {
 ** used to create the initializers for the FuncDef structures.
 **
 **   FUNCTION(zName, nArg, iArg, bNC, xFunc)
-**     Used to create a scalar function definition of a function zName 
+**     Used to create a scalar function definition of a function zName
 **     implemented by C function xFunc that accepts nArg arguments. The
 **     value passed as iArg is cast to a (void*) and made available
-**     as the user-data (sqlite3_user_data()) for the function. If 
+**     as the user-data (sqlite3_user_data()) for the function. If
 **     argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
 **
 **   VFUNCTION(zName, nArg, iArg, bNC, xFunc)
@@ -12371,8 +14009,8 @@ struct FuncDestructor {
 **     FUNCTION().
 **
 **   LIKEFUNC(zName, nArg, pArg, flags)
-**     Used to create a scalar function definition of a function zName 
-**     that accepts nArg arguments and is implemented by a call to C 
+**     Used to create a scalar function definition of a function zName
+**     that accepts nArg arguments and is implemented by a call to C
 **     function likeFunc. Argument pArg is cast to a (void *) and made
 **     available as the function user-data (sqlite3_user_data()). The
 **     FuncDef.flags variable is set to the value passed as the flags
@@ -12380,28 +14018,28 @@ struct FuncDestructor {
 */
 #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
 #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
   {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
 #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
 #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
   {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
 #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
-   pArg, 0, xFunc, 0, #zName, 0, 0}
+   pArg, 0, xFunc, 0, #zName, }
 #define LIKEFUNC(zName, nArg, arg, flags) \
   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
-   (void *)arg, 0, likeFunc, 0, #zName, 0, 0}
+   (void *)arg, 0, likeFunc, 0, #zName, {0} }
 #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
-   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0}
+   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
 #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
-   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0}
+   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
 
 /*
 ** All current savepoints are stored in a linked list starting at
@@ -12443,10 +14081,8 @@ struct Module {
 ** of this structure.
 */
 struct Column {
-  char *zName;     /* Name of this column */
+  char *zName;     /* Name of this column, \000, then the type */
   Expr *pDflt;     /* Default value of this column */
-  char *zDflt;     /* Original text of the default value */
-  char *zType;     /* Data type for this column */
   char *zColl;     /* Collating sequence.  If NULL, use the default */
   u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
   char affinity;   /* One of the SQLITE_AFF_... values */
@@ -12458,6 +14094,7 @@ struct Column {
 */
 #define COLFLAG_PRIMKEY  0x0001    /* Column is part of the primary key */
 #define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
+#define COLFLAG_HASTYPE  0x0004    /* Type name follows column name */
 
 /*
 ** A "Collating Sequence" is defined by an instance of the following
@@ -12488,7 +14125,7 @@ struct CollSeq {
 **
 ** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
 ** 't' for SQLITE_AFF_TEXT.  But we can save a little space and improve
-** the speed a little by numbering the values consecutively.  
+** the speed a little by numbering the values consecutively.
 **
 ** But rather than start with 0 or 1, we begin with 'A'.  That way,
 ** when multiple affinity types are concatenated into a string and
@@ -12507,7 +14144,7 @@ struct CollSeq {
 
 /*
 ** The SQLITE_AFF_MASK values masks off the significant bits of an
-** affinity value. 
+** affinity value.
 */
 #define SQLITE_AFF_MASK     0x47
 
@@ -12527,20 +14164,20 @@ struct CollSeq {
 
 /*
 ** An object of this type is created for each virtual table present in
-** the database schema. 
+** the database schema.
 **
 ** If the database schema is shared, then there is one instance of this
 ** structure for each database connection (sqlite3*) that uses the shared
 ** schema. This is because each database connection requires its own unique
-** instance of the sqlite3_vtab* handle used to access the virtual table 
-** implementation. sqlite3_vtab* handles can not be shared between 
-** database connections, even when the rest of the in-memory database 
+** instance of the sqlite3_vtab* handle used to access the virtual table
+** implementation. sqlite3_vtab* handles can not be shared between
+** database connections, even when the rest of the in-memory database
 ** schema is shared, as the implementation often stores the database
 ** connection handle passed to it via the xConnect() or xCreate() method
 ** during initialization internally. This database connection handle may
-** then be used by the virtual table implementation to access real tables 
-** within the database. So that they appear as part of the callers 
-** transaction, these accesses need to be made via the same database 
+** then be used by the virtual table implementation to access real tables
+** within the database. So that they appear as part of the callers
+** transaction, these accesses need to be made via the same database
 ** connection as that used to execute SQL operations on the virtual table.
 **
 ** All VTable objects that correspond to a single table in a shared
@@ -12552,19 +14189,19 @@ struct CollSeq {
 ** sqlite3_vtab* handle in the compiled query.
 **
 ** When an in-memory Table object is deleted (for example when the
-** schema is being reloaded for some reason), the VTable objects are not 
-** deleted and the sqlite3_vtab* handles are not xDisconnect()ed 
+** schema is being reloaded for some reason), the VTable objects are not
+** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
 ** immediately. Instead, they are moved from the Table.pVTable list to
 ** another linked list headed by the sqlite3.pDisconnect member of the
-** corresponding sqlite3 structure. They are then deleted/xDisconnected 
+** corresponding sqlite3 structure. They are then deleted/xDisconnected
 ** next time a statement is prepared using said sqlite3*. This is done
 ** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
 ** Refer to comments above function sqlite3VtabUnlockList() for an
 ** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
 ** list without holding the corresponding sqlite3.mutex mutex.
 **
-** The memory for objects of this type is always allocated by 
-** sqlite3DbMalloc(), using the connection handle stored in VTable.db as 
+** The memory for objects of this type is always allocated by
+** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
 ** the first argument.
 */
 struct VTable {
@@ -12732,7 +14369,7 @@ struct FKey {
 ** key is set to NULL.  CASCADE means that a DELETE or UPDATE of the
 ** referenced table row is propagated into the row that holds the
 ** foreign key.
-** 
+**
 ** The following symbolic values are used to record which type
 ** of action to take.
 */
@@ -12753,7 +14390,7 @@ struct FKey {
 
 /*
 ** An instance of the following structure is passed as the first
-** argument to sqlite3VdbeKeyCompare and is used to control the 
+** argument to sqlite3VdbeKeyCompare and is used to control the
 ** comparison of the two index keys.
 **
 ** Note that aSortOrder[] and aColl[] have nField+1 slots.  There
@@ -12794,7 +14431,7 @@ struct KeyInfo {
 ** The key comparison functions actually return default_rc when they find
 ** an equals comparison.  default_rc can be -1, 0, or +1.  If there are
 ** multiple entries in the b-tree with the same key (when only looking
-** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to 
+** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
 ** cause the search to find the last match, or +1 to cause the search to
 ** find the first match.
 **
@@ -12831,7 +14468,7 @@ struct UnpackedRecord {
 ** In the Table structure describing Ex1, nCol==3 because there are
 ** three columns in the table.  In the Index structure describing
 ** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
-** The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the 
+** The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the
 ** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
 ** The second column to be indexed (c1) has an index of 0 in
 ** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
@@ -12839,7 +14476,7 @@ struct UnpackedRecord {
 ** The Index.onError field determines whether or not the indexed columns
 ** must be unique and what to do if they are not.  When Index.onError=OE_None,
 ** it means this is not a unique index.  Otherwise it is a unique index
-** and the value of Index.onError indicate the which conflict resolution 
+** and the value of Index.onError indicate the which conflict resolution
 ** algorithm to employ whenever an attempt is made to insert a non-unique
 ** element.
 **
@@ -12904,7 +14541,7 @@ struct Index {
 #define XN_EXPR      (-2)     /* Indexed column is an expression */
 
 /*
-** Each sample stored in the sqlite_stat3 table is represented in memory 
+** Each sample stored in the sqlite_stat3 table is represented in memory
 ** using a structure of this type.  See documentation at the top of the
 ** analyze.c source file for additional information.
 */
@@ -12999,9 +14636,9 @@ typedef int ynVar;
 ** to represent the greater-than-or-equal-to operator in the expression
 ** tree.
 **
-** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, 
+** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
 ** or TK_STRING), then Expr.token contains the text of the SQL literal. If
-** the expression is a variable (TK_VARIABLE), then Expr.token contains the 
+** the expression is a variable (TK_VARIABLE), then Expr.token contains the
 ** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
 ** then Expr.token contains the name of the function.
 **
@@ -13012,7 +14649,7 @@ typedef int ynVar;
 ** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
 ** Expr.x.pSelect is used if the expression is a sub-select or an expression of
 ** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
-** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is 
+** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
 ** valid.
 **
 ** An expression of the form ID or ID.ID refers to a column in a table.
@@ -13023,8 +14660,8 @@ typedef int ynVar;
 ** value is also stored in the Expr.iAgg column in the aggregate so that
 ** it can be accessed after all aggregates are computed.
 **
-** If the expression is an unbound variable marker (a question mark 
-** character '?' in the original SQL) then the Expr.iTable holds the index 
+** If the expression is an unbound variable marker (a question mark
+** character '?' in the original SQL) then the Expr.iTable holds the index
 ** number for that variable.
 **
 ** If the expression is a subquery then Expr.iColumn holds an integer
@@ -13063,7 +14700,7 @@ struct Expr {
 
   /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
   ** space is allocated for the fields below this point. An attempt to
-  ** access them will result in a segfault or malfunction. 
+  ** access them will result in a segfault or malfunction.
   *********************************************************************/
 
   Expr *pLeft;           /* Left subnode */
@@ -13129,7 +14766,7 @@ struct Expr {
 #define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
 
 /*
-** These macros can be used to test, set, or clear bits in the 
+** These macros can be used to test, set, or clear bits in the
 ** Expr.flags field.
 */
 #define ExprHasProperty(E,P)     (((E)->flags&(P))!=0)
@@ -13148,8 +14785,8 @@ struct Expr {
 #endif
 
 /*
-** Macros to determine the number of bytes required by a normal Expr 
-** struct, an Expr struct with the EP_Reduced flag set in Expr.flags 
+** Macros to determine the number of bytes required by a normal Expr
+** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
 ** and an Expr struct with the EP_TokenOnly flag set.
 */
 #define EXPR_FULLSIZE           sizeof(Expr)           /* Full size */
@@ -13157,7 +14794,7 @@ struct Expr {
 #define EXPR_TOKENONLYSIZE      offsetof(Expr,pLeft)   /* Fewer features */
 
 /*
-** Flags passed to the sqlite3ExprDup() function. See the header comment 
+** Flags passed to the sqlite3ExprDup() function. See the header comment
 ** above sqlite3ExprDup() for details.
 */
 #define EXPRDUP_REDUCE         0x0001  /* Used reduced-size Expr nodes */
@@ -13239,7 +14876,11 @@ struct IdList {
 ** tables in a join to 32 instead of 64.  But it also reduces the size
 ** of the library by 738 bytes on ix86.
 */
-typedef u64 Bitmask;
+#ifdef SQLITE_BITMASK_TYPE
+  typedef SQLITE_BITMASK_TYPE Bitmask;
+#else
+  typedef u64 Bitmask;
+#endif
 
 /*
 ** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
@@ -13251,6 +14892,7 @@ typedef u64 Bitmask;
 */
 #define MASKBIT(n)   (((Bitmask)1)<<(n))
 #define MASKBIT32(n) (((unsigned int)1)<<(n))
+#define ALLBITS      ((Bitmask)-1)
 
 /*
 ** The following structure describes the FROM clause of a SELECT statement.
@@ -13323,6 +14965,9 @@ struct SrcList {
 /*
 ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
 ** and the WhereInfo.wctrlFlags member.
+**
+** Value constraints (enforced via assert()):
+**     WHERE_USE_LIMIT  == SF_FixedLimit
 */
 #define WHERE_ORDERBY_NORMAL   0x0000 /* No-op */
 #define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
@@ -13339,6 +14984,8 @@ struct SrcList {
 #define WHERE_SORTBYGROUP      0x0800 /* Support sqlite3WhereIsSorted() */
 #define WHERE_REOPEN_IDX       0x1000 /* Try to use OP_ReopenIdx */
 #define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */
+#define WHERE_USE_LIMIT        0x4000 /* There is a constant LIMIT clause */
+#define WHERE_SEEK_TABLE       0x8000 /* Do not defer seeks on main table */
 
 /* Allowed return values from sqlite3WhereIsDistinct()
 */
@@ -13356,12 +15003,12 @@ struct SrcList {
 ** pEList corresponds to the result set of a SELECT and is NULL for
 ** other statements.
 **
-** NameContexts can be nested.  When resolving names, the inner-most 
+** NameContexts can be nested.  When resolving names, the inner-most
 ** context is searched first.  If no match is found, the next outer
 ** context is checked.  If there is still no match, the next context
 ** is checked.  This process continues until either a match is found
 ** or all contexts are check.  When a match is found, the nRef member of
-** the context containing the match is incremented. 
+** the context containing the match is incremented.
 **
 ** Each subquery gets a new NameContext.  The pNext field points to the
 ** NameContext in the parent query.  Thus the process of scanning the
@@ -13382,16 +15029,18 @@ struct NameContext {
 /*
 ** Allowed values for the NameContext, ncFlags field.
 **
-** Note:  NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
-** SQLITE_FUNC_MINMAX.
-** 
+** Value constraints (all checked via assert()):
+**    NC_HasAgg    == SF_HasAgg
+**    NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
+**
 */
 #define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
-#define NC_HasAgg    0x0002  /* One or more aggregate functions seen */
+#define NC_PartIdx   0x0002  /* True if resolving a partial index WHERE */
 #define NC_IsCheck   0x0004  /* True if resolving names in a CHECK constraint */
 #define NC_InAggFunc 0x0008  /* True if analyzing arguments to an agg func */
-#define NC_PartIdx   0x0010  /* True if resolving a partial index WHERE */
+#define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
 #define NC_IdxExpr   0x0020  /* True if resolving columns of CREATE INDEX */
+#define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
 #define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
 
 /*
@@ -13417,13 +15066,13 @@ struct NameContext {
 struct Select {
   ExprList *pEList;      /* The fields of the result */
   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
-  u16 selFlags;          /* Various SF_* values */
+  LogEst nSelectRow;     /* Estimated number of result rows */
+  u32 selFlags;          /* Various SF_* values */
   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
 #if SELECTTRACE_ENABLED
   char zSelName[12];     /* Symbolic name of this SELECT use for debugging */
 #endif
   int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
-  u64 nSelectRow;        /* Estimated number of result rows */
   SrcList *pSrc;         /* The FROM clause */
   Expr *pWhere;          /* The WHERE clause */
   ExprList *pGroupBy;    /* The GROUP BY clause */
@@ -13439,23 +15088,30 @@ struct Select {
 /*
 ** Allowed values for Select.selFlags.  The "SF" prefix stands for
 ** "Select Flag".
-*/
-#define SF_Distinct        0x0001  /* Output should be DISTINCT */
-#define SF_All             0x0002  /* Includes the ALL keyword */
-#define SF_Resolved        0x0004  /* Identifiers have been resolved */
-#define SF_Aggregate       0x0008  /* Contains aggregate functions */
-#define SF_UsesEphemeral   0x0010  /* Uses the OpenEphemeral opcode */
-#define SF_Expanded        0x0020  /* sqlite3SelectExpand() called on this */
-#define SF_HasTypeInfo     0x0040  /* FROM subqueries have Table metadata */
-#define SF_Compound        0x0080  /* Part of a compound query */
-#define SF_Values          0x0100  /* Synthesized from VALUES clause */
-#define SF_MultiValue      0x0200  /* Single VALUES term with multiple rows */
-#define SF_NestedFrom      0x0400  /* Part of a parenthesized FROM clause */
-#define SF_MaybeConvert    0x0800  /* Need convertCompoundSelectToSubquery() */
-#define SF_MinMaxAgg       0x1000  /* Aggregate containing min() or max() */
-#define SF_Recursive       0x2000  /* The recursive part of a recursive CTE */
-#define SF_Converted       0x4000  /* By convertCompoundSelectToSubquery() */
-#define SF_IncludeHidden   0x8000  /* Include hidden columns in output */
+**
+** Value constraints (all checked via assert())
+**     SF_HasAgg     == NC_HasAgg
+**     SF_MinMaxAgg  == NC_MinMaxAgg     == SQLITE_FUNC_MINMAX
+**     SF_FixedLimit == WHERE_USE_LIMIT
+*/
+#define SF_Distinct       0x00001  /* Output should be DISTINCT */
+#define SF_All            0x00002  /* Includes the ALL keyword */
+#define SF_Resolved       0x00004  /* Identifiers have been resolved */
+#define SF_Aggregate      0x00008  /* Contains agg functions or a GROUP BY */
+#define SF_HasAgg         0x00010  /* Contains aggregate functions */
+#define SF_UsesEphemeral  0x00020  /* Uses the OpenEphemeral opcode */
+#define SF_Expanded       0x00040  /* sqlite3SelectExpand() called on this */
+#define SF_HasTypeInfo    0x00080  /* FROM subqueries have Table metadata */
+#define SF_Compound       0x00100  /* Part of a compound query */
+#define SF_Values         0x00200  /* Synthesized from VALUES clause */
+#define SF_MultiValue     0x00400  /* Single VALUES term with multiple rows */
+#define SF_NestedFrom     0x00800  /* Part of a parenthesized FROM clause */
+#define SF_MinMaxAgg      0x01000  /* Aggregate containing min() or max() */
+#define SF_Recursive      0x02000  /* The recursive part of a recursive CTE */
+#define SF_FixedLimit     0x04000  /* nSelectRow set by a constant LIMIT */
+#define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
+#define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
+#define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
 
 
 /*
@@ -13463,7 +15119,7 @@ struct Select {
 ** by one of the following macros.  The "SRT" prefix means "SELECT Result
 ** Type".
 **
-**     SRT_Union       Store results as a key in a temporary index 
+**     SRT_Union       Store results as a key in a temporary index
 **                     identified by pDest->iSDParm.
 **
 **     SRT_Except      Remove results from the temporary index pDest->iSDParm.
@@ -13487,7 +15143,7 @@ struct Select {
 **                     of the query.  This destination implies "LIMIT 1".
 **
 **     SRT_Set         The result must be a single column.  Store each
-**                     row of result as the key in table pDest->iSDParm. 
+**                     row of result as the key in table pDest->iSDParm.
 **                     Apply the affinity pDest->affSdst before storing
 **                     results.  Used to implement "IN (SELECT ...)".
 **
@@ -13555,7 +15211,7 @@ struct SelectDest {
 };
 
 /*
-** During code generation of statements that do inserts into AUTOINCREMENT 
+** During code generation of statements that do inserts into AUTOINCREMENT
 ** tables, the following information is attached to the Table.u.autoInc.p
 ** pointer of each autoincrement table to record some side information that
 ** the code generator needs.  We have to keep per-table autoincrement
@@ -13578,7 +15234,7 @@ struct AutoincInfo {
 #endif
 
 /*
-** At least one instance of the following structure is created for each 
+** At least one instance of the following structure is created for each
 ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
 ** statement. All such objects are stored in the linked list headed at
 ** Parse.pTriggerPrg and deleted once statement compilation has been
@@ -13591,7 +15247,7 @@ struct AutoincInfo {
 ** values for both pTrigger and orconf.
 **
 ** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns
-** accessed (or set to 0 for triggers fired as a result of INSERT 
+** accessed (or set to 0 for triggers fired as a result of INSERT
 ** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
 ** a mask of new.* columns used by the program.
 */
@@ -13632,7 +15288,7 @@ struct TriggerPrg {
 ** is constant but the second part is reset at the beginning and end of
 ** each recursion.
 **
-** The nTableLock and aTableLock variables are only used if the shared-cache 
+** The nTableLock and aTableLock variables are only used if the shared-cache
 ** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
 ** used to store the set of table-locks required by the statement being
 ** compiled. Function sqlite3TableLock() is used to add entries to the
@@ -13652,6 +15308,7 @@ struct Parse {
   u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
   u8 okConstFactor;    /* OK to factor out constants */
   u8 disableLookaside; /* Number of times lookaside has been disabled */
+  u8 nColCache;        /* Number of entries in aColCache[] */
   int aTempReg[8];     /* Holding area for temporary registers */
   int nRangeReg;       /* Size of the temporary register block */
   int iRangeReg;       /* First register in temporary register block */
@@ -13765,6 +15422,15 @@ struct AuthContext {
 
 /*
 ** Bitfield flags for P5 value in various opcodes.
+**
+** Value constraints (enforced via assert()):
+**    OPFLAG_LENGTHARG    == SQLITE_FUNC_LENGTH
+**    OPFLAG_TYPEOFARG    == SQLITE_FUNC_TYPEOF
+**    OPFLAG_BULKCSR      == BTREE_BULKLOAD
+**    OPFLAG_SEEKEQ       == BTREE_SEEK_EQ
+**    OPFLAG_FORDELETE    == BTREE_FORDELETE
+**    OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
+**    OPFLAG_AUXDELETE    == BTREE_AUXDELETE
 */
 #define OPFLAG_NCHANGE       0x01    /* OP_Insert: Set to update db->nChange */
                                      /* Also used in P2 (not P5) of OP_Delete */
@@ -13773,6 +15439,9 @@ struct AuthContext {
 #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
 #define OPFLAG_APPEND        0x08    /* This is likely to be an append */
 #define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+#define OPFLAG_ISNOOP        0x40    /* OP_Delete does pre-update-hook only */
+#endif
 #define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
 #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
 #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
@@ -13785,10 +15454,10 @@ struct AuthContext {
 
 /*
  * Each trigger present in the database schema is stored as an instance of
- * struct Trigger. 
+ * struct Trigger.
  *
  * Pointers to instances of struct Trigger are stored in two ways.
- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
+ * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
  *    database). This allows Trigger structures to be retrieved by name.
  * 2. All triggers associated with a single table form a linked list, using the
  *    pNext member of struct Trigger. A pointer to the first element of the
@@ -13814,7 +15483,7 @@ struct Trigger {
 
 /*
 ** A trigger is either a BEFORE or an AFTER trigger.  The following constants
-** determine which. 
+** determine which.
 **
 ** If there are multiple triggers, you might of some BEFORE and some AFTER.
 ** In that cases, the constants below can be ORed together.
@@ -13824,15 +15493,15 @@ struct Trigger {
 
 /*
  * An instance of struct TriggerStep is used to store a single SQL statement
- * that is a part of a trigger-program. 
+ * that is a part of a trigger-program.
  *
  * Instances of struct TriggerStep are stored in a singly linked list (linked
- * using the "pNext" member) referenced by the "step_list" member of the 
+ * using the "pNext" member) referenced by the "step_list" member of the
  * associated struct Trigger instance. The first element of the linked list is
  * the first step of the trigger-program.
- * 
+ *
  * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
- * "SELECT" statement. The meanings of the other members is determined by the 
+ * "SELECT" statement. The meanings of the other members is determined by the
  * value of "op" as follows:
  *
  * (op == TK_INSERT)
@@ -13842,7 +15511,7 @@ struct Trigger {
  * zTarget   -> Dequoted name of the table to insert into.
  * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
  *              this stores values to be inserted. Otherwise NULL.
- * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
+ * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ...
  *              statement, then this stores the column-names to be
  *              inserted into.
  *
@@ -13850,7 +15519,7 @@ struct Trigger {
  * zTarget   -> Dequoted name of the table to delete from.
  * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
  *              Otherwise NULL.
- * 
+ *
  * (op == TK_UPDATE)
  * zTarget   -> Dequoted name of the table to update.
  * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
@@ -13858,7 +15527,7 @@ struct Trigger {
  * pExprList -> A list of the columns to update and the expressions to update
  *              them to. See sqlite3Update() documentation of "pChanges"
  *              argument.
- * 
+ *
  */
 struct TriggerStep {
   u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
@@ -13876,7 +15545,7 @@ struct TriggerStep {
 /*
 ** The following structure contains information used by the sqliteFix...
 ** routines as they walk the parse tree to make database references
-** explicit.  
+** explicit.
 */
 typedef struct DbFixer DbFixer;
 struct DbFixer {
@@ -13952,6 +15621,7 @@ struct Sqlite3Config {
   int mxStrlen;                     /* Maximum string length */
   int szLookaside;                  /* Default lookaside buffer size */
   int nLookaside;                   /* Default lookaside buffer count */
+  int nStmtSpill;                   /* Stmt-journal spill-to-disk threshold */
   sqlite3_mem_methods m;            /* Low-level memory allocation interface */
   sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
   sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
@@ -14102,6 +15772,15 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
 #define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
 #define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
 #define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE   int sqlite3NomemError(int);
+SQLITE_PRIVATE   int sqlite3IoerrnomemError(int);
+# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
+# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
+#else
+# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
+# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
+#endif
 
 /*
 ** FTS3 and FTS4 both require virtual table support
@@ -14142,6 +15821,7 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
 # define sqlite3Isdigit(x)   (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
 # define sqlite3Isxdigit(x)  (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
 # define sqlite3Tolower(x)   (sqlite3UpperToLower[(unsigned char)(x)])
+# define sqlite3Isquote(x)   (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
 #else
 # define sqlite3Toupper(x)   toupper((unsigned char)(x))
 # define sqlite3Isspace(x)   isspace((unsigned char)(x))
@@ -14150,6 +15830,7 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
 # define sqlite3Isdigit(x)   isdigit((unsigned char)(x))
 # define sqlite3Isxdigit(x)  isxdigit((unsigned char)(x))
 # define sqlite3Tolower(x)   tolower((unsigned char)(x))
+# define sqlite3Isquote(x)   ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
 #endif
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 SQLITE_PRIVATE int sqlite3IsIdChar(u8);
@@ -14158,8 +15839,9 @@ SQLITE_PRIVATE int sqlite3IsIdChar(u8);
 /*
 ** Internal function prototypes
 */
-#define sqlite3StrICmp sqlite3_stricmp
+SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
 SQLITE_PRIVATE int sqlite3Strlen30(const char*);
+SQLITE_PRIVATE const char *sqlite3ColumnType(Column*,const char*);
 #define sqlite3StrNICmp sqlite3_strnicmp
 
 SQLITE_PRIVATE int sqlite3MallocInit(void);
@@ -14198,7 +15880,7 @@ SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
 #ifdef SQLITE_USE_ALLOCA
 # define sqlite3StackAllocRaw(D,N)   alloca(N)
 # define sqlite3StackAllocZero(D,N)  memset(alloca(N), 0, N)
-# define sqlite3StackFree(D,P)       
+# define sqlite3StackFree(D,P)
 #else
 # define sqlite3StackAllocRaw(D,N)   sqlite3DbMallocRaw(D,N)
 # define sqlite3StackAllocZero(D,N)  sqlite3DbMallocZero(D,N)
@@ -14272,7 +15954,7 @@ SQLITE_PRIVATE   void sqlite3TreeViewWith(TreeView*, const With*, u8);
 
 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
-SQLITE_PRIVATE int sqlite3Dequote(char*);
+SQLITE_PRIVATE void sqlite3Dequote(char*);
 SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
 SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
 SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
@@ -14282,10 +15964,14 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
 SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
 SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
 SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int);
+#endif
 SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
 SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
 SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
+SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
 SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
 SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
@@ -14305,6 +15991,7 @@ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
 SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
 SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*);
 SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
+SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*);
 SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
 SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
 SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
@@ -14315,11 +16002,10 @@ SQLITE_PRIVATE   void sqlite3ColumnPropertiesFromName(Table*, Column*);
 #else
 # define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
 #endif
-SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*);
+SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*,Token*);
 SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
 SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
 SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
-SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
 SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
 SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
 SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
@@ -14393,19 +16079,19 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*
 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
-                         Expr*,ExprList*,u16,Expr*,Expr*);
+                         Expr*,ExprList*,u32,Expr*,Expr*);
 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
+SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,const char*);
 #endif
 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
-SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*);
+SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
 SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
 SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
 SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
@@ -14505,11 +16191,11 @@ SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
 #else
 # define sqlite3SelectSetName(A,B)
 #endif
-SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
-SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
+SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
+SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
+SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
+SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
 SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
 SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
 SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
@@ -14588,7 +16274,11 @@ SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
 #endif
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
+    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
+    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
+#endif
 
 /*
 ** Routines to read and write variable-length integers.  These used to
@@ -14623,6 +16313,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
 SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
 SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
 SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
+SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int);
 SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
 SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
 SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
@@ -14655,7 +16346,7 @@ SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8);
 
 SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
-SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
+SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
                         void(*)(void*));
 SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
@@ -14670,7 +16361,7 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
 SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
 SQLITE_PRIVATE const Token sqlite3IntTokens[];
 SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
 #ifndef SQLITE_OMIT_WSD
 SQLITE_PRIVATE int sqlite3PendingByte;
 #endif
@@ -14715,7 +16406,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
 #ifdef SQLITE_DEBUG
 SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
 #endif
-SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
+SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
   void (*)(sqlite3_context*,int,sqlite3_value **),
   void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
   FuncDestructor *pDestructor
@@ -14778,7 +16469,7 @@ SQLITE_PRIVATE   int sqlite3Utf8To8(unsigned char*);
 #  define sqlite3VtabRollback(X)
 #  define sqlite3VtabCommit(X)
 #  define sqlite3VtabInSync(db) 0
-#  define sqlite3VtabLock(X) 
+#  define sqlite3VtabLock(X)
 #  define sqlite3VtabUnlock(X)
 #  define sqlite3VtabUnlockList(X)
 #  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
@@ -14836,7 +16527,7 @@ SQLITE_PRIVATE   void sqlite3WithPush(Parse*, With*, u8);
 ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
 ** key functionality is available. If OMIT_TRIGGER is defined but
 ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
-** this case foreign keys are parsed, but no other functionality is 
+** this case foreign keys are parsed, but no other functionality is
 ** provided (enforcement of FK constraints requires the triggers sub-system).
 */
 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
@@ -14897,19 +16588,14 @@ SQLITE_PRIVATE   void sqlite3EndBenignMalloc(void);
 #define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
 SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*);
 
+SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
+SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
 #ifdef SQLITE_ENABLE_ATOMIC_WRITE
-SQLITE_PRIVATE   int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
-SQLITE_PRIVATE   int sqlite3JournalSize(sqlite3_vfs *);
 SQLITE_PRIVATE   int sqlite3JournalCreate(sqlite3_file *);
-SQLITE_PRIVATE   int sqlite3JournalExists(sqlite3_file *p);
-#else
-  #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
-  #define sqlite3JournalExists(p) 1
 #endif
 
+SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p);
 SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
-SQLITE_PRIVATE int sqlite3MemJournalSize(void);
-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);
 
 SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
 #if SQLITE_MAX_EXPR_DEPTH>0
@@ -14940,7 +16626,7 @@ SQLITE_PRIVATE   void sqlite3ParserTrace(FILE*, char *);
 /*
 ** If the SQLITE_ENABLE IOTRACE exists then the global variable
 ** sqlite3IoTrace is a pointer to a printf-like routine used to
-** print I/O tracing messages. 
+** print I/O tracing messages.
 */
 #ifdef SQLITE_ENABLE_IOTRACE
 # define IOTRACE(A)  if( sqlite3IoTrace ){ sqlite3IoTrace A; }
@@ -14974,7 +16660,7 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
 ** that allocations that might have been satisfied by lookaside are not
 ** passed back to non-lookaside free() routines.  Asserts such as the
 ** example above are placed on the non-lookaside free() routines to verify
-** this constraint. 
+** this constraint.
 **
 ** All of this is no-op for a production build.  It only comes into
 ** play when the SQLITE_MEMDEBUG compile-time option is used.
@@ -15081,6 +16767,7 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
 **   isxdigit()                       0x08
 **   toupper()                        0x20
 **   SQLite identifier character      0x40
+**   Quote character                  0x80
 **
 ** Bit 0x20 is set if the mapped character requires translation to upper
 ** case. i.e. if the character is a lower-case ASCII character.
@@ -15106,7 +16793,7 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
   0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
-  0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  /* 20..27     !"#$%&' */
+  0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80,  /* 20..27     !"#$%&' */
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,  /* 30..37    01234567 */
   0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 38..3f    89:;<=>? */
@@ -15114,8 +16801,8 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
   0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,  /* 40..47    @ABCDEFG */
   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 48..4f    HIJKLMNO */
   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 50..57    PQRSTUVW */
-  0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
-  0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
+  0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
+  0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 68..6f    hijklmno */
   0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 70..77    pqrstuvw */
   0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 78..7f    xyz{|}~. */
@@ -15170,6 +16857,18 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
 # define SQLITE_SORTER_PMASZ 250
 #endif
 
+/* Statement journals spill to disk when their size exceeds the following
+** threashold (in bytes). 0 means that statement journals are created and
+** written to disk immediately (the default behavior for SQLite versions
+** before 3.12.0).  -1 means always keep the entire statement journal in
+** memory.  (The statement journal is also always held entirely in memory
+** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
+** setting.)
+*/
+#ifndef SQLITE_STMTJRNL_SPILL 
+# define SQLITE_STMTJRNL_SPILL (64*1024)
+#endif
+
 /*
 ** The following singleton contains the global configuration for
 ** the SQLite library.
@@ -15183,6 +16882,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
    0x7ffffffe,                /* mxStrlen */
    128,                       /* szLookaside */
    500,                       /* nLookaside */
+   SQLITE_STMTJRNL_SPILL,     /* nStmtSpill */
    {0,0,0,0,0,0,0,0},         /* m */
    {0,0,0,0,0,0,0,0,0},       /* mutex */
    {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
@@ -15230,7 +16930,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
 ** database connections.  After initialization, this table is
 ** read-only.
 */
-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
 
 /*
 ** Constant tokens for values 0 and 1.
@@ -15831,7 +17531,7 @@ struct VdbeCursor {
 #endif
   Bool isEphemeral:1;   /* True for an ephemeral table */
   Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
-  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
+  Bool isOrdered:1;     /* True if the table is not BTREE_UNORDERED */
   Pgno pgnoRoot;        /* Root page of the open btree cursor */
   i16 nField;           /* Number of fields in the header */
   u16 nHdrParsed;       /* Number of header fields parsed so far */
@@ -15905,6 +17605,7 @@ struct VdbeFrame {
   VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
   void *token;            /* Copy of SubProgram.token */
   i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
+  AuxData *pAuxData;      /* Linked list of auxdata allocations */
   int nCursor;            /* Number of entries in apCsr */
   int pc;                 /* Program Counter in parent (calling) frame */
   int nOp;                /* Size of aOp array */
@@ -16124,16 +17825,16 @@ struct Vdbe {
 #endif
   u16 nResColumn;         /* Number of columns in one row of the result set */
   u8 errorAction;         /* Recovery action to do in case of an error */
+  bft expired:1;          /* True if the VM needs to be recompiled */
+  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
   u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   bft explain:2;          /* True if EXPLAIN present on SQL command */
   bft changeCntOn:1;      /* True to update the change-counter */
-  bft expired:1;          /* True if the VM needs to be recompiled */
   bft runOnlyOnce:1;      /* Automatically expire on reset */
   bft usesStmtJournal:1;  /* True if uses a statement journal */
   bft readOnly:1;         /* True for statements that do not write */
   bft bIsReader:1;        /* True for statements that read */
   bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
-  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
   int nChange;            /* Number of db changes made since last reset */
   yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
   yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
@@ -16172,6 +17873,25 @@ struct Vdbe {
 #define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
 
 /*
+** Structure used to store the context required by the 
+** sqlite3_preupdate_*() API functions.
+*/
+struct PreUpdate {
+  Vdbe *v;
+  VdbeCursor *pCsr;               /* Cursor to read old values from */
+  int op;                         /* One of SQLITE_INSERT, UPDATE, DELETE */
+  u8 *aRecord;                    /* old.* database record */
+  KeyInfo keyinfo;
+  UnpackedRecord *pUnpacked;      /* Unpacked version of aRecord[] */
+  UnpackedRecord *pNewUnpacked;   /* Unpacked version of new.* record */
+  int iNewReg;                    /* Register for new.* values */
+  i64 iKey1;                      /* First key value passed to hook */
+  i64 iKey2;                      /* Second key value passed to hook */
+  int iPKey;                      /* If not negative index of IPK column */
+  Mem *aNew;                      /* Array of new.* values */
+};
+
+/*
 ** Function prototypes
 */
 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
@@ -16187,7 +17907,7 @@ SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*);
 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
 SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
 
 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
@@ -16230,6 +17950,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
 SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
 SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
 SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
+#endif
 SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
 
 SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
@@ -16658,6 +18381,15 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
 
 #ifndef SQLITE_OMIT_DATETIME_FUNCS
 
+/*
+** The MSVC CRT on Windows CE may not have a localtime() function.
+** So declare a substitute.  The substitute function itself is
+** defined in "os_win.c".
+*/
+#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
+    (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
+struct tm *__cdecl localtime(const time_t *);
+#endif
 
 /*
 ** A structure for holding a single date and time.
@@ -17026,6 +18758,7 @@ static void clearYMD_HMS_TZ(DateTime *p){
   p->validTZ = 0;
 }
 
+#ifndef SQLITE_OMIT_LOCALTIME
 /*
 ** On recent Windows platforms, the localtime_s() function is available
 ** as part of the "Secure CRT". It is essentially equivalent to 
@@ -17044,7 +18777,6 @@ static void clearYMD_HMS_TZ(DateTime *p){
 #define HAVE_LOCALTIME_S 1
 #endif
 
-#ifndef SQLITE_OMIT_LOCALTIME
 /*
 ** The following routine implements the rough equivalent of localtime_r()
 ** using whatever operating-system specific localtime facility that
@@ -17755,7 +19487,7 @@ static void currentTimeFunc(
 ** external linkage.
 */
 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
-  static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
+  static FuncDef aDateTimeFuncs[] = {
 #ifndef SQLITE_OMIT_DATETIME_FUNCS
     DFUNCTION(julianday,        -1, 0, 0, juliandayFunc ),
     DFUNCTION(date,             -1, 0, 0, dateFunc      ),
@@ -17771,13 +19503,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
     STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
 #endif
   };
-  int i;
-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
-
-  for(i=0; i<ArraySize(aDateTimeFuncs); i++){
-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
-  }
+  sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
 }
 
 /************** End of date.c ************************************************/
@@ -17850,9 +19576,9 @@ SQLITE_API int sqlite3_open_file_count = 0;
 #if defined(SQLITE_TEST)
 SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
   #define DO_OS_MALLOC_TEST(x)                                       \
-  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
+  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \
     void *pTstAlloc = sqlite3Malloc(10);                             \
-    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
+    if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT;                  \
     sqlite3_free(pTstAlloc);                                         \
   }
 #else
@@ -17865,13 +19591,11 @@ SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
 ** of this would be completely automatic if SQLite were coded using
 ** C++ instead of plain old C.
 */
-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
-  int rc = SQLITE_OK;
+SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file *pId){
   if( pId->pMethods ){
-    rc = pId->pMethods->xClose(pId);
+    pId->pMethods->xClose(pId);
     pId->pMethods = 0;
   }
-  return rc;
 }
 SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
   DO_OS_MALLOC_TEST(id);
@@ -18046,6 +19770,9 @@ SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufO
 SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
   return pVfs->xSleep(pVfs, nMicro);
 }
+SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
+  return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
+}
 SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
   int rc;
   /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
@@ -18071,7 +19798,7 @@ SQLITE_PRIVATE int sqlite3OsOpenMalloc(
   int flags,
   int *pOutFlags
 ){
-  int rc = SQLITE_NOMEM;
+  int rc;
   sqlite3_file *pFile;
   pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
   if( pFile ){
@@ -18081,15 +19808,15 @@ SQLITE_PRIVATE int sqlite3OsOpenMalloc(
     }else{
       *ppFile = pFile;
     }
+  }else{
+    rc = SQLITE_NOMEM_BKPT;
   }
   return rc;
 }
-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){
-  int rc = SQLITE_OK;
+SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
   assert( pFile );
-  rc = sqlite3OsClose(pFile);
+  sqlite3OsClose(pFile);
   sqlite3_free(pFile);
-  return rc;
 }
 
 /*
@@ -18100,7 +19827,7 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){
 */
 SQLITE_PRIVATE int sqlite3OsInit(void){
   void *p = sqlite3Malloc(10);
-  if( p==0 ) return SQLITE_NOMEM;
+  if( p==0 ) return SQLITE_NOMEM_BKPT;
   sqlite3_free(p);
   return sqlite3_os_init();
 }
@@ -22744,7 +24471,7 @@ SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){
 static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
   sqlite3OomClear(db);
   sqlite3Error(db, SQLITE_NOMEM);
-  return SQLITE_NOMEM;
+  return SQLITE_NOMEM_BKPT;
 }
 
 /*
@@ -22791,26 +24518,26 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
 ** Conversion types fall into various categories as defined by the
 ** following enumeration.
 */
-#define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
-#define etFLOAT       2 /* Floating point.  %f */
-#define etEXP         3 /* Exponentional notation. %e and %E */
-#define etGENERIC     4 /* Floating or exponential, depending on exponent. %g */
-#define etSIZE        5 /* Return number of characters processed so far. %n */
-#define etSTRING      6 /* Strings. %s */
-#define etDYNSTRING   7 /* Dynamically allocated strings. %z */
-#define etPERCENT     8 /* Percent symbol. %% */
-#define etCHARX       9 /* Characters. %c */
+#define etRADIX       0 /* Integer types.  %d, %x, %o, and so forth */
+#define etFLOAT       1 /* Floating point.  %f */
+#define etEXP         2 /* Exponentional notation. %e and %E */
+#define etGENERIC     3 /* Floating or exponential, depending on exponent. %g */
+#define etSIZE        4 /* Return number of characters processed so far. %n */
+#define etSTRING      5 /* Strings. %s */
+#define etDYNSTRING   6 /* Dynamically allocated strings. %z */
+#define etPERCENT     7 /* Percent symbol. %% */
+#define etCHARX       8 /* Characters. %c */
 /* The rest are extensions, not normally found in printf() */
-#define etSQLESCAPE  10 /* Strings with '\'' doubled.  %q */
-#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
+#define etSQLESCAPE   9 /* Strings with '\'' doubled.  %q */
+#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '',
                           NULL pointers replaced by SQL NULL.  %Q */
-#define etTOKEN      12 /* a pointer to a Token structure */
-#define etSRCLIST    13 /* a pointer to a SrcList */
-#define etPOINTER    14 /* The %p conversion */
-#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
-#define etORDINAL    16 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
+#define etTOKEN      11 /* a pointer to a Token structure */
+#define etSRCLIST    12 /* a pointer to a SrcList */
+#define etPOINTER    13 /* The %p conversion */
+#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
+#define etORDINAL    15 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
 
-#define etINVALID     0 /* Any unrecognized conversion type */
+#define etINVALID    16 /* Any unrecognized conversion type */
 
 
 /*
@@ -22965,7 +24692,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
   etByte flag_long;          /* True if "l" flag is present */
   etByte flag_longlong;      /* True if the "ll" flag is present */
   etByte done;               /* Loop termination flag */
-  etByte xtype = 0;          /* Conversion paradigm */
+  etByte xtype = etINVALID;  /* Conversion paradigm */
   u8 bArgList;               /* True for SQLITE_PRINTF_SQLFUNC */
   u8 useIntern;              /* Ok to use internal conversions (ex: %T) */
   char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
@@ -23250,7 +24977,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
         exp = 0;
         if( sqlite3IsNaN((double)realvalue) ){
-          bufpt = "NaN";
+          bufpt = (char *)"NaN";
           length = 3;
           break;
         }
@@ -23420,7 +25147,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           bufpt = va_arg(ap,char*);
         }
         if( bufpt==0 ){
-          bufpt = "";
+          bufpt = (char *)"";
         }else if( xtype==etDYNSTRING ){
           zExtra = bufpt;
         }
@@ -23437,7 +25164,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         int needQuote;
         char ch;
         char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
-        char *escarg;
+        const char *escarg;
 
         if( bArgList ){
           escarg = getTextArg(pArgList);
@@ -24003,9 +25730,10 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
     sqlite3TreeViewPush(pView, 1);
   }
   do{
-    sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
+    sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
       ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
-      ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
+      ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
+      (int)p->nSelectRow
     );
     if( cnt++ ) sqlite3TreeViewPop(pView);
     if( p->pPrior ){
@@ -24209,6 +25937,12 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
     case TK_ISNULL:  zUniOp = "ISNULL"; break;
     case TK_NOTNULL: zUniOp = "NOTNULL"; break;
 
+    case TK_SPAN: {
+      sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
+      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+      break;
+    }
+
     case TK_COLLATE: {
       sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
       sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
@@ -24560,7 +26294,7 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
 
   *ppThread = 0;
   p = sqlite3Malloc(sizeof(*p));
-  if( p==0 ) return SQLITE_NOMEM;
+  if( p==0 ) return SQLITE_NOMEM_BKPT;
   memset(p, 0, sizeof(*p));
   p->xTask = xTask;
   p->pIn = pIn;
@@ -24586,7 +26320,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
   int rc;
 
   assert( ppOut!=0 );
-  if( NEVER(p==0) ) return SQLITE_NOMEM;
+  if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
   if( p->done ){
     *ppOut = p->pOut;
     rc = SQLITE_OK;
@@ -24651,7 +26385,7 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
   assert( xTask!=0 );
   *ppThread = 0;
   p = sqlite3Malloc(sizeof(*p));
-  if( p==0 ) return SQLITE_NOMEM;
+  if( p==0 ) return SQLITE_NOMEM_BKPT;
   /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a 
   ** function that returns SQLITE_ERROR when passed the argument 200, that
   ** forces worker threads to run sequentially and deterministically 
@@ -24682,7 +26416,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
   DWORD rc;
 
   assert( ppOut!=0 );
-  if( NEVER(p==0) ) return SQLITE_NOMEM;
+  if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
   if( p->xTask==0 ){
     /* assert( p->id==GetCurrentThreadId() ); */
     rc = WAIT_OBJECT_0;
@@ -24729,7 +26463,7 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
   assert( xTask!=0 );
   *ppThread = 0;
   p = sqlite3Malloc(sizeof(*p));
-  if( p==0 ) return SQLITE_NOMEM;
+  if( p==0 ) return SQLITE_NOMEM_BKPT;
   if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
     p->xTask = xTask;
     p->pIn = pIn;
@@ -24745,7 +26479,7 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
 SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
 
   assert( ppOut!=0 );
-  if( NEVER(p==0) ) return SQLITE_NOMEM;
+  if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
   if( p->xTask ){
     *ppOut = p->xTask(p->pIn);
   }else{
@@ -24756,7 +26490,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
 #if defined(SQLITE_TEST)
   {
     void *pTstAlloc = sqlite3Malloc(10);
-    if (!pTstAlloc) return SQLITE_NOMEM;
+    if (!pTstAlloc) return SQLITE_NOMEM_BKPT;
     sqlite3_free(pTstAlloc);
   }
 #endif
@@ -25003,7 +26737,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
     rc = sqlite3VdbeMemMakeWriteable(pMem);
     if( rc!=SQLITE_OK ){
       assert( rc==SQLITE_NOMEM );
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     zIn = (u8*)pMem->z;
     zTerm = &zIn[pMem->n&~1];
@@ -25045,7 +26779,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
   zTerm = &zIn[pMem->n];
   zOut = sqlite3DbMallocRaw(pMem->db, len);
   if( !zOut ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   z = zOut;
 
@@ -25415,12 +27149,48 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
 }
 
 /*
+** Return the declared type of a column.  Or return zDflt if the column 
+** has no declared type.
+**
+** The column type is an extra string stored after the zero-terminator on
+** the column name if and only if the COLFLAG_HASTYPE flag is set.
+*/
+SQLITE_PRIVATE const char *sqlite3ColumnType(Column *pCol, const char *zDflt){
+  if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt;
+  return pCol->zName + strlen(pCol->zName) + 1;
+}
+
+/*
+** Helper function for sqlite3Error() - called rarely.  Broken out into
+** a separate routine to avoid unnecessary register saves on entry to
+** sqlite3Error().
+*/
+static SQLITE_NOINLINE void  sqlite3ErrorFinish(sqlite3 *db, int err_code){
+  if( db->pErr ) sqlite3ValueSetNull(db->pErr);
+  sqlite3SystemError(db, err_code);
+}
+
+/*
 ** Set the current error code to err_code and clear any prior error message.
+** Also set iSysErrno (by calling sqlite3System) if the err_code indicates
+** that would be appropriate.
 */
 SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){
   assert( db!=0 );
   db->errCode = err_code;
-  if( db->pErr ) sqlite3ValueSetNull(db->pErr);
+  if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
+}
+
+/*
+** Load the sqlite3.iSysErrno field if that is an appropriate thing
+** to do based on the SQLite error code in rc.
+*/
+SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
+  if( rc==SQLITE_IOERR_NOMEM ) return;
+  rc &= 0xff;
+  if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){
+    db->iSysErrno = sqlite3OsGetLastError(db->pVfs);
+  }
 }
 
 /*
@@ -25447,6 +27217,7 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){
 SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
   assert( db!=0 );
   db->errCode = err_code;
+  sqlite3SystemError(db, err_code);
   if( zFormat==0 ){
     sqlite3Error(db, err_code);
   }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
@@ -25510,18 +27281,13 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
 ** brackets from around identifiers.  For example:  "[a-b-c]" becomes
 ** "a-b-c".
 */
-SQLITE_PRIVATE int sqlite3Dequote(char *z){
+SQLITE_PRIVATE void sqlite3Dequote(char *z){
   char quote;
   int i, j;
-  if( z==0 ) return -1;
+  if( z==0 ) return;
   quote = z[0];
-  switch( quote ){
-    case '\'':  break;
-    case '"':   break;
-    case '`':   break;                /* For MySQL compatibility */
-    case '[':   quote = ']';  break;  /* For MS SqlServer compatibility */
-    default:    return -1;
-  }
+  if( !sqlite3Isquote(quote) ) return;
+  if( quote=='[' ) quote = ']';
   for(i=1, j=0;; i++){
     assert( z[i] );
     if( z[i]==quote ){
@@ -25536,7 +27302,6 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){
     }
   }
   z[j] = 0;
-  return j;
 }
 
 /*
@@ -25561,16 +27326,25 @@ SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){
 ** independence" that SQLite uses internally when comparing identifiers.
 */
 SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){
-  register unsigned char *a, *b;
   if( zLeft==0 ){
     return zRight ? -1 : 0;
   }else if( zRight==0 ){
     return 1;
   }
+  return sqlite3StrICmp(zLeft, zRight);
+}
+SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
+  unsigned char *a, *b;
+  int c;
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
-  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
-  return UpperToLower[*a] - UpperToLower[*b];
+  for(;;){
+    c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
+    if( c || *a==0 ) break;
+    a++;
+    b++;
+  }
+  return c;
 }
 SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
   register unsigned char *a, *b;
@@ -25620,7 +27394,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
   int eValid = 1;  /* True exponent is either not used or is well-formed */
   double result;
   int nDigits = 0;
-  int nonNum = 0;
+  int nonNum = 0;  /* True if input contains UTF16 with high byte non-zero */
 
   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
   *pResult = 0.0;   /* Default return value, in case of an error */
@@ -25633,7 +27407,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
     assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
     for(i=3-enc; i<length && z[i]==0; i+=2){}
     nonNum = i<length;
-    zEnd = z+i+enc-3;
+    zEnd = &z[i^1];
     z += (enc&1);
   }
 
@@ -25649,9 +27423,6 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
     z+=incr;
   }
 
-  /* skip leading zeroes */
-  while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
-
   /* copy max significant digits to significand */
   while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
     s = s*10 + (*z - '0');
@@ -25668,12 +27439,13 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
     z+=incr;
     /* copy digits from after decimal to significand
     ** (decrease exponent by d to shift decimal right) */
-    while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
-      s = s*10 + (*z - '0');
-      z+=incr, nDigits++, d--;
+    while( z<zEnd && sqlite3Isdigit(*z) ){
+      if( s<((LARGEST_INT64-9)/10) ){
+        s = s*10 + (*z - '0');
+        d--;
+      }
+      z+=incr, nDigits++;
     }
-    /* skip non-significant digits */
-    while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
   }
   if( z>=zEnd ) goto do_atof_calc;
 
@@ -25681,7 +27453,12 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
   if( *z=='e' || *z=='E' ){
     z+=incr;
     eValid = 0;
-    if( z>=zEnd ) goto do_atof_calc;
+
+    /* This branch is needed to avoid a (harmless) buffer overread.  The 
+    ** special comment alerts the mutation tester that the correct answer
+    ** is obtained even if the branch is omitted */
+    if( z>=zEnd ) goto do_atof_calc;              /*PREVENTS-HARMLESS-OVERREAD*/
+
     /* get sign of exponent */
     if( *z=='-' ){
       esign = -1;
@@ -25698,9 +27475,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
   }
 
   /* skip trailing spaces */
-  if( nDigits && eValid ){
-    while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
-  }
+  while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
 
 do_atof_calc:
   /* adjust exponent by d, and update sign */
@@ -25712,41 +27487,51 @@ do_atof_calc:
     esign = 1;
   }
 
-  /* if 0 significand */
-  if( !s ) {
-    /* In the IEEE 754 standard, zero is signed.
-    ** Add the sign if we've seen at least one digit */
-    result = (sign<0 && nDigits) ? -(double)0 : (double)0;
+  if( s==0 ) {
+    /* In the IEEE 754 standard, zero is signed. */
+    result = sign<0 ? -(double)0 : (double)0;
   } else {
-    /* attempt to reduce exponent */
-    if( esign>0 ){
-      while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
-    }else{
-      while( !(s%10) && e>0 ) e--,s/=10;
+    /* Attempt to reduce exponent.
+    **
+    ** Branches that are not required for the correct answer but which only
+    ** help to obtain the correct answer faster are marked with special
+    ** comments, as a hint to the mutation tester.
+    */
+    while( e>0 ){                                       /*OPTIMIZATION-IF-TRUE*/
+      if( esign>0 ){
+        if( s>=(LARGEST_INT64/10) ) break;             /*OPTIMIZATION-IF-FALSE*/
+        s *= 10;
+      }else{
+        if( s%10!=0 ) break;                           /*OPTIMIZATION-IF-FALSE*/
+        s /= 10;
+      }
+      e--;
     }
 
     /* adjust the sign of significand */
     s = sign<0 ? -s : s;
 
-    /* if exponent, scale significand as appropriate
-    ** and store in result. */
-    if( e ){
+    if( e==0 ){                                         /*OPTIMIZATION-IF-TRUE*/
+      result = (double)s;
+    }else{
       LONGDOUBLE_TYPE scale = 1.0;
       /* attempt to handle extremely small/large numbers better */
-      if( e>307 && e<342 ){
-        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
-        if( esign<0 ){
-          result = s / scale;
-          result /= 1.0e+308;
-        }else{
-          result = s * scale;
-          result *= 1.0e+308;
-        }
-      }else if( e>=342 ){
-        if( esign<0 ){
-          result = 0.0*s;
-        }else{
-          result = 1e308*1e308*s;  /* Infinity */
+      if( e>307 ){                                      /*OPTIMIZATION-IF-TRUE*/
+        if( e<342 ){                                    /*OPTIMIZATION-IF-TRUE*/
+          while( e%308 ) { scale *= 1.0e+1; e -= 1; }
+          if( esign<0 ){
+            result = s / scale;
+            result /= 1.0e+308;
+          }else{
+            result = s * scale;
+            result *= 1.0e+308;
+          }
+        }else{ assert( e>=342 );
+          if( esign<0 ){
+            result = 0.0*s;
+          }else{
+            result = 1e308*1e308*s;  /* Infinity */
+          }
         }
       }else{
         /* 1.0e+22 is the largest power of 10 than can be 
@@ -25759,8 +27544,6 @@ do_atof_calc:
           result = s * scale;
         }
       }
-    } else {
-      result = (double)s;
     }
   }
 
@@ -25768,7 +27551,7 @@ do_atof_calc:
   *pResult = result;
 
   /* return true if number and no extra non-whitespace chracters after */
-  return z>=zEnd && nDigits>0 && eValid && nonNum==0;
+  return z==zEnd && nDigits>0 && eValid && nonNum==0;
 #else
   return !sqlite3Atoi64(z, pResult, length, enc);
 #endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -25830,7 +27613,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
   int neg = 0; /* assume positive */
   int i;
   int c = 0;
-  int nonNum = 0;
+  int nonNum = 0;  /* True if input contains UTF16 with high byte non-zero */
   const char *zStart;
   const char *zEnd = zNum + length;
   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
@@ -25841,7 +27624,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
     assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
     for(i=3-enc; i<length && zNum[i]==0; i+=2){}
     nonNum = i<length;
-    zEnd = zNum+i+enc-3;
+    zEnd = &zNum[i^1];
     zNum += (enc&1);
   }
   while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
@@ -25868,8 +27651,11 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
   testcase( i==18 );
   testcase( i==19 );
   testcase( i==20 );
-  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum)
-       || i>19*incr || nonNum ){
+  if( &zNum[i]<zEnd              /* Extra bytes at the end */
+   || (i==0 && zStart==zNum)     /* No digits */
+   || i>19*incr                  /* Too many digits */
+   || nonNum                     /* UTF16 with high-order bytes non-zero */
+  ){
     /* zNum is empty or contains non-numeric text or is longer
     ** than 19 digits (thus guaranteeing that it is too large) */
     return 1;
@@ -25911,7 +27697,6 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
 #ifndef SQLITE_OMIT_HEX_INTEGER
   if( z[0]=='0'
    && (z[1]=='x' || z[1]=='X')
-   && sqlite3Isxdigit(z[2])
   ){
     u64 u = 0;
     int i, k;
@@ -26381,7 +28166,7 @@ SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
 */
 SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
   int i;
-  for(i=1; (v >>= 7)!=0; i++){ assert( i<9 ); }
+  for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); }
   return i;
 }
 
@@ -26412,10 +28197,12 @@ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
 SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
 #if SQLITE_BYTEORDER==4321
   memcpy(p,&v,4);
-#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+    && defined(__GNUC__) && GCC_VERSION>=4003000
   u32 x = __builtin_bswap32(v);
   memcpy(p,&x,4);
-#elif SQLITE_BYTEORDER==1234 && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+    && defined(_MSC_VER) && _MSC_VER>=1300
   u32 x = _byteswap_ulong(v);
   memcpy(p,&x,4);
 #else
@@ -26671,7 +28458,7 @@ SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){
     if( x<2 ) return 0;
     while( x<8 ){  y -= 10; x <<= 1; }
   }else{
-    while( x>255 ){ y += 40; x >>= 4; }
+    while( x>255 ){ y += 40; x >>= 4; }  /*OPTIMIZATION-IF-TRUE*/
     while( x>15 ){  y += 10; x >>= 1; }
   }
   return a[x&7] + y - 10;
@@ -26694,21 +28481,32 @@ SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
+    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
+    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
 /*
 ** Convert a LogEst into an integer.
+**
+** Note that this routine is only used when one or more of various
+** non-standard compile-time options is enabled.
 */
 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
   u64 n;
-  if( x<10 ) return 1;
   n = x%10;
   x /= 10;
   if( n>=5 ) n -= 2;
   else if( n>=1 ) n -= 1;
-  if( x>=3 ){
-    return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3);
-  }
-  return (n+8)>>(3-x);
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
+    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
+  if( x>60 ) return (u64)LARGEST_INT64;
+#else
+  /* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input
+  ** possible to this routine is 310, resulting in a maximum x of 31 */
+  assert( x<=60 );
+#endif
+  return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
 }
+#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
 
 /************** End of util.c ************************************************/
 /************** Begin file hash.c ********************************************/
@@ -26769,7 +28567,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
 static unsigned int strHash(const char *z){
   unsigned int h = 0;
   unsigned char c;
-  while( (c = (unsigned char)*z++)!=0 ){
+  while( (c = (unsigned char)*z++)!=0 ){     /*OPTIMIZATION-IF-TRUE*/
     h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
   }
   return h;
@@ -26862,7 +28660,7 @@ static HashElem *findElementWithHash(
   int count;                     /* Number of elements left to test */
   unsigned int h;                /* The computed hash */
 
-  if( pH->ht ){
+  if( pH->ht ){   /*OPTIMIZATION-IF-TRUE*/
     struct _ht *pEntry;
     h = strHash(pKey) % pH->htsize;
     pEntry = &pH->ht[h];
@@ -27009,153 +28807,152 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
     /*  12 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
     /*  13 */ "Goto"             OpHelp(""),
     /*  14 */ "Gosub"            OpHelp(""),
-    /*  15 */ "Return"           OpHelp(""),
-    /*  16 */ "InitCoroutine"    OpHelp(""),
-    /*  17 */ "EndCoroutine"     OpHelp(""),
-    /*  18 */ "Yield"            OpHelp(""),
+    /*  15 */ "InitCoroutine"    OpHelp(""),
+    /*  16 */ "Yield"            OpHelp(""),
+    /*  17 */ "MustBeInt"        OpHelp(""),
+    /*  18 */ "Jump"             OpHelp(""),
     /*  19 */ "Not"              OpHelp("r[P2]= !r[P1]"),
-    /*  20 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
-    /*  21 */ "Halt"             OpHelp(""),
-    /*  22 */ "Integer"          OpHelp("r[P2]=P1"),
-    /*  23 */ "Int64"            OpHelp("r[P2]=P4"),
-    /*  24 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
-    /*  25 */ "Null"             OpHelp("r[P2..P3]=NULL"),
-    /*  26 */ "SoftNull"         OpHelp("r[P1]=NULL"),
-    /*  27 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
-    /*  28 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
-    /*  29 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
-    /*  30 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
-    /*  31 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
-    /*  32 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
-    /*  33 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
-    /*  34 */ "CollSeq"          OpHelp(""),
-    /*  35 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
-    /*  36 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
-    /*  37 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
-    /*  38 */ "MustBeInt"        OpHelp(""),
-    /*  39 */ "RealAffinity"     OpHelp(""),
-    /*  40 */ "Cast"             OpHelp("affinity(r[P1])"),
-    /*  41 */ "Permutation"      OpHelp(""),
-    /*  42 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
-    /*  43 */ "Jump"             OpHelp(""),
-    /*  44 */ "Once"             OpHelp(""),
-    /*  45 */ "If"               OpHelp(""),
-    /*  46 */ "IfNot"            OpHelp(""),
-    /*  47 */ "Column"           OpHelp("r[P3]=PX"),
-    /*  48 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
-    /*  49 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
-    /*  50 */ "Count"            OpHelp("r[P2]=count()"),
-    /*  51 */ "ReadCookie"       OpHelp(""),
-    /*  52 */ "SetCookie"        OpHelp(""),
-    /*  53 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
-    /*  54 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
-    /*  55 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
-    /*  56 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
-    /*  57 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
-    /*  58 */ "SorterOpen"       OpHelp(""),
-    /*  59 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
-    /*  60 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
-    /*  61 */ "Close"            OpHelp(""),
-    /*  62 */ "ColumnsUsed"      OpHelp(""),
-    /*  63 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
-    /*  64 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
-    /*  65 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
-    /*  66 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
-    /*  67 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
-    /*  68 */ "NotFound"         OpHelp("key=r[P3@P4]"),
-    /*  69 */ "Found"            OpHelp("key=r[P3@P4]"),
-    /*  70 */ "NotExists"        OpHelp("intkey=r[P3]"),
-    /*  71 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
-    /*  72 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
-    /*  73 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
-    /*  74 */ "NewRowid"         OpHelp("r[P2]=rowid"),
-    /*  75 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
-    /*  76 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
-    /*  77 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
-    /*  78 */ "Ne"               OpHelp("if r[P1]!=r[P3] goto P2"),
-    /*  79 */ "Eq"               OpHelp("if r[P1]==r[P3] goto P2"),
-    /*  80 */ "Gt"               OpHelp("if r[P1]>r[P3] goto P2"),
-    /*  81 */ "Le"               OpHelp("if r[P1]<=r[P3] goto P2"),
-    /*  82 */ "Lt"               OpHelp("if r[P1]<r[P3] goto P2"),
-    /*  83 */ "Ge"               OpHelp("if r[P1]>=r[P3] goto P2"),
-    /*  84 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
-    /*  85 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
-    /*  86 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
-    /*  87 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
-    /*  88 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
-    /*  89 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
-    /*  90 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
-    /*  91 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
-    /*  92 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
-    /*  93 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
-    /*  94 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
-    /*  95 */ "Delete"           OpHelp(""),
-    /*  96 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
+    /*  20 */ "Once"             OpHelp(""),
+    /*  21 */ "If"               OpHelp(""),
+    /*  22 */ "IfNot"            OpHelp(""),
+    /*  23 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
+    /*  24 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
+    /*  25 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
+    /*  26 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
+    /*  27 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
+    /*  28 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
+    /*  29 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
+    /*  30 */ "NotFound"         OpHelp("key=r[P3@P4]"),
+    /*  31 */ "Found"            OpHelp("key=r[P3@P4]"),
+    /*  32 */ "NotExists"        OpHelp("intkey=r[P3]"),
+    /*  33 */ "Last"             OpHelp(""),
+    /*  34 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
+    /*  35 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
+    /*  36 */ "Ne"               OpHelp("if r[P1]!=r[P3] goto P2"),
+    /*  37 */ "Eq"               OpHelp("if r[P1]==r[P3] goto P2"),
+    /*  38 */ "Gt"               OpHelp("if r[P1]>r[P3] goto P2"),
+    /*  39 */ "Le"               OpHelp("if r[P1]<=r[P3] goto P2"),
+    /*  40 */ "Lt"               OpHelp("if r[P1]<r[P3] goto P2"),
+    /*  41 */ "Ge"               OpHelp("if r[P1]>=r[P3] goto P2"),
+    /*  42 */ "SorterSort"       OpHelp(""),
+    /*  43 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
+    /*  44 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
+    /*  45 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
+    /*  46 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
+    /*  47 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
+    /*  48 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
+    /*  49 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
+    /*  50 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
+    /*  51 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
+    /*  52 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
+    /*  53 */ "Sort"             OpHelp(""),
+    /*  54 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
+    /*  55 */ "Rewind"           OpHelp(""),
+    /*  56 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
+    /*  57 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
+    /*  58 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
+    /*  59 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
+    /*  60 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
+    /*  61 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
+    /*  62 */ "Program"          OpHelp(""),
+    /*  63 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
+    /*  64 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+    /*  65 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]-=P3, goto P2"),
+    /*  66 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
+    /*  67 */ "IncrVacuum"       OpHelp(""),
+    /*  68 */ "VNext"            OpHelp(""),
+    /*  69 */ "Init"             OpHelp("Start at P2"),
+    /*  70 */ "Return"           OpHelp(""),
+    /*  71 */ "EndCoroutine"     OpHelp(""),
+    /*  72 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
+    /*  73 */ "Halt"             OpHelp(""),
+    /*  74 */ "Integer"          OpHelp("r[P2]=P1"),
+    /*  75 */ "Int64"            OpHelp("r[P2]=P4"),
+    /*  76 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
+    /*  77 */ "Null"             OpHelp("r[P2..P3]=NULL"),
+    /*  78 */ "SoftNull"         OpHelp("r[P1]=NULL"),
+    /*  79 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
+    /*  80 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
+    /*  81 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
+    /*  82 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+    /*  83 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
+    /*  84 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
+    /*  85 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
+    /*  86 */ "CollSeq"          OpHelp(""),
+    /*  87 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
+    /*  88 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
+    /*  89 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
+    /*  90 */ "RealAffinity"     OpHelp(""),
+    /*  91 */ "Cast"             OpHelp("affinity(r[P1])"),
+    /*  92 */ "Permutation"      OpHelp(""),
+    /*  93 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
+    /*  94 */ "Column"           OpHelp("r[P3]=PX"),
+    /*  95 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
+    /*  96 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
     /*  97 */ "String8"          OpHelp("r[P2]='P4'"),
-    /*  98 */ "ResetCount"       OpHelp(""),
-    /*  99 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
-    /* 100 */ "SorterData"       OpHelp("r[P2]=data"),
-    /* 101 */ "RowKey"           OpHelp("r[P2]=key"),
-    /* 102 */ "RowData"          OpHelp("r[P2]=data"),
-    /* 103 */ "Rowid"            OpHelp("r[P2]=rowid"),
-    /* 104 */ "NullRow"          OpHelp(""),
-    /* 105 */ "Last"             OpHelp(""),
-    /* 106 */ "SorterSort"       OpHelp(""),
-    /* 107 */ "Sort"             OpHelp(""),
-    /* 108 */ "Rewind"           OpHelp(""),
-    /* 109 */ "SorterInsert"     OpHelp(""),
-    /* 110 */ "IdxInsert"        OpHelp("key=r[P2]"),
-    /* 111 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
-    /* 112 */ "Seek"             OpHelp("Move P3 to P1.rowid"),
-    /* 113 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
-    /* 114 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
-    /* 115 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
-    /* 116 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
-    /* 117 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
-    /* 118 */ "Destroy"          OpHelp(""),
-    /* 119 */ "Clear"            OpHelp(""),
-    /* 120 */ "ResetSorter"      OpHelp(""),
-    /* 121 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
-    /* 122 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
-    /* 123 */ "ParseSchema"      OpHelp(""),
-    /* 124 */ "LoadAnalysis"     OpHelp(""),
-    /* 125 */ "DropTable"        OpHelp(""),
-    /* 126 */ "DropIndex"        OpHelp(""),
-    /* 127 */ "DropTrigger"      OpHelp(""),
-    /* 128 */ "IntegrityCk"      OpHelp(""),
-    /* 129 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
-    /* 130 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
-    /* 131 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
-    /* 132 */ "Program"          OpHelp(""),
+    /*  98 */ "Count"            OpHelp("r[P2]=count()"),
+    /*  99 */ "ReadCookie"       OpHelp(""),
+    /* 100 */ "SetCookie"        OpHelp(""),
+    /* 101 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
+    /* 102 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+    /* 103 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
+    /* 104 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
+    /* 105 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
+    /* 106 */ "SorterOpen"       OpHelp(""),
+    /* 107 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+    /* 108 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
+    /* 109 */ "Close"            OpHelp(""),
+    /* 110 */ "ColumnsUsed"      OpHelp(""),
+    /* 111 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
+    /* 112 */ "NewRowid"         OpHelp("r[P2]=rowid"),
+    /* 113 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
+    /* 114 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
+    /* 115 */ "Delete"           OpHelp(""),
+    /* 116 */ "ResetCount"       OpHelp(""),
+    /* 117 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+    /* 118 */ "SorterData"       OpHelp("r[P2]=data"),
+    /* 119 */ "RowKey"           OpHelp("r[P2]=key"),
+    /* 120 */ "RowData"          OpHelp("r[P2]=data"),
+    /* 121 */ "Rowid"            OpHelp("r[P2]=rowid"),
+    /* 122 */ "NullRow"          OpHelp(""),
+    /* 123 */ "SorterInsert"     OpHelp(""),
+    /* 124 */ "IdxInsert"        OpHelp("key=r[P2]"),
+    /* 125 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
+    /* 126 */ "Seek"             OpHelp("Move P3 to P1.rowid"),
+    /* 127 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+    /* 128 */ "Destroy"          OpHelp(""),
+    /* 129 */ "Clear"            OpHelp(""),
+    /* 130 */ "ResetSorter"      OpHelp(""),
+    /* 131 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
+    /* 132 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
     /* 133 */ "Real"             OpHelp("r[P2]=P4"),
-    /* 134 */ "Param"            OpHelp(""),
-    /* 135 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
-    /* 136 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
-    /* 137 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
-    /* 138 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
-    /* 139 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
-    /* 140 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]-=P3, goto P2"),
-    /* 141 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
-    /* 142 */ "JumpZeroIncr"     OpHelp("if (r[P1]++)==0 ) goto P2"),
-    /* 143 */ "AggStep0"         OpHelp("accum=r[P3] step(r[P2@P5])"),
-    /* 144 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
-    /* 145 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
-    /* 146 */ "IncrVacuum"       OpHelp(""),
-    /* 147 */ "Expire"           OpHelp(""),
-    /* 148 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
-    /* 149 */ "VBegin"           OpHelp(""),
-    /* 150 */ "VCreate"          OpHelp(""),
-    /* 151 */ "VDestroy"         OpHelp(""),
-    /* 152 */ "VOpen"            OpHelp(""),
-    /* 153 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
-    /* 154 */ "VNext"            OpHelp(""),
+    /* 134 */ "ParseSchema"      OpHelp(""),
+    /* 135 */ "LoadAnalysis"     OpHelp(""),
+    /* 136 */ "DropTable"        OpHelp(""),
+    /* 137 */ "DropIndex"        OpHelp(""),
+    /* 138 */ "DropTrigger"      OpHelp(""),
+    /* 139 */ "IntegrityCk"      OpHelp(""),
+    /* 140 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
+    /* 141 */ "Param"            OpHelp(""),
+    /* 142 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
+    /* 143 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
+    /* 144 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+    /* 145 */ "AggStep0"         OpHelp("accum=r[P3] step(r[P2@P5])"),
+    /* 146 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
+    /* 147 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
+    /* 148 */ "Expire"           OpHelp(""),
+    /* 149 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
+    /* 150 */ "VBegin"           OpHelp(""),
+    /* 151 */ "VCreate"          OpHelp(""),
+    /* 152 */ "VDestroy"         OpHelp(""),
+    /* 153 */ "VOpen"            OpHelp(""),
+    /* 154 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
     /* 155 */ "VRename"          OpHelp(""),
     /* 156 */ "Pagecount"        OpHelp(""),
     /* 157 */ "MaxPgcnt"         OpHelp(""),
-    /* 158 */ "Init"             OpHelp("Start at P2"),
-    /* 159 */ "CursorHint"       OpHelp(""),
-    /* 160 */ "Noop"             OpHelp(""),
-    /* 161 */ "Explain"          OpHelp(""),
+    /* 158 */ "CursorHint"       OpHelp(""),
+    /* 159 */ "Noop"             OpHelp(""),
+    /* 160 */ "Explain"          OpHelp(""),
   };
   return azName[i];
 }
@@ -27236,6 +29033,19 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 #  endif
 #endif
 
+/* Use pread() and pwrite() if they are available */
+#if defined(__APPLE__)
+# define HAVE_PREAD 1
+# define HAVE_PWRITE 1
+#endif
+#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64)
+# undef USE_PREAD
+# define USE_PREAD64 1
+#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE)
+# undef USE_PREAD64
+# define USE_PREAD 1
+#endif
+
 /*
 ** standard include files.
 */
@@ -27755,7 +29565,7 @@ static struct unix_syscall {
 #else
   { "pread64",      (sqlite3_syscall_ptr)0,          0  },
 #endif
-#define osPread64   ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
+#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
 
   { "write",        (sqlite3_syscall_ptr)write,      0  },
 #define osWrite     ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
@@ -27773,7 +29583,7 @@ static struct unix_syscall {
 #else
   { "pwrite64",     (sqlite3_syscall_ptr)0,          0  },
 #endif
-#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
+#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off64_t))\
                     aSyscall[13].pCurrent)
 
   { "fchmod",       (sqlite3_syscall_ptr)fchmod,          0  },
@@ -28472,7 +30282,7 @@ static int unixLogErrorAtLine(
   const char *zPath,              /* File path associated with error */
   int iLine                       /* Source line number where error occurred */
 ){
-  char *zErr;                     /* Message from strerror() or equivalent */
+  const char *zErr;               /* Message from strerror() or equivalent */
   int iErrno = errno;             /* Saved syscall error number */
 
   /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
@@ -28665,7 +30475,7 @@ static int findInodeInfo(
   if( pInode==0 ){
     pInode = sqlite3_malloc64( sizeof(*pInode) );
     if( pInode==0 ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     memset(pInode, 0, sizeof(*pInode));
     memcpy(&pInode->fileId, &fileId, sizeof(fileId));
@@ -28707,12 +30517,16 @@ static int fileHasMoved(unixFile *pFile){
 static void verifyDbFile(unixFile *pFile){
   struct stat buf;
   int rc;
+
+  /* These verifications occurs for the main database only */
+  if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return;
+
   rc = osFstat(pFile->h, &buf);
   if( rc!=0 ){
     sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
     return;
   }
-  if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
+  if( buf.st_nlink==0 ){
     sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
     return;
   }
@@ -28848,7 +30662,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
   ** lock transitions in terms of the POSIX advisory shared and exclusive
   ** lock primitives (called read-locks and write-locks below, to avoid
   ** confusion with SQLite lock names). The algorithms are complicated
-  ** slightly in order to be compatible with windows systems simultaneously
+  ** slightly in order to be compatible with Windows95 systems simultaneously
   ** accessing the same database file, in case that is ever required.
   **
   ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
@@ -28856,8 +30670,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){
   ** range', a range of 510 bytes at a well known offset.
   **
   ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
-  ** byte'.  If this is successful, a random byte from the 'shared byte
-  ** range' is read-locked and the lock on the 'pending byte' released.
+  ** byte'.  If this is successful, 'shared byte range' is read-locked
+  ** and the lock on the 'pending byte' released.  (Legacy note:  When
+  ** SQLite was first developed, Windows95 systems were still very common,
+  ** and Widnows95 lacks a shared-lock capability.  So on Windows95, a
+  ** single randomly selected by from the 'shared byte range' is locked.
+  ** Windows95 is now pretty much extinct, but this work-around for the
+  ** lack of shared-locks on Windows95 lives on, for backwards
+  ** compatibility.)
   **
   ** A process may only obtain a RESERVED lock after it has a SHARED lock.
   ** A RESERVED lock is implemented by grabbing a write-lock on the
@@ -28876,11 +30696,6 @@ static int unixLock(sqlite3_file *id, int eFileLock){
   ** range'. Since all other locks require a read-lock on one of the bytes
   ** within this range, this ensures that no other locks are held on the
   ** database. 
-  **
-  ** The reason a single byte cannot be used instead of the 'shared byte
-  ** range' is that some versions of windows do not support read-locks. By
-  ** locking a random byte from a range, concurrent SHARED locks may exist
-  ** even if the locking primitive used is always a write-lock.
   */
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
@@ -31585,7 +33400,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
 
   /* Allocate space for the new unixShm object. */
   p = sqlite3_malloc64( sizeof(*p) );
-  if( p==0 ) return SQLITE_NOMEM;
+  if( p==0 ) return SQLITE_NOMEM_BKPT;
   memset(p, 0, sizeof(*p));
   assert( pDbFd->pShm==0 );
 
@@ -31617,7 +33432,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
 #endif
     pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
     if( pShmNode==0 ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
       goto shm_open_err;
     }
     memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
@@ -31633,10 +33448,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
     pShmNode->h = -1;
     pDbFd->pInode->pShmNode = pShmNode;
     pShmNode->pInode = pDbFd->pInode;
-    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-    if( pShmNode->mutex==0 ){
-      rc = SQLITE_NOMEM;
-      goto shm_open_err;
+    if( sqlite3GlobalConfig.bCoreMutex ){
+      pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+      if( pShmNode->mutex==0 ){
+        rc = SQLITE_NOMEM_BKPT;
+        goto shm_open_err;
+      }
     }
 
     if( pInode->bProcessLock==0 ){
@@ -31808,7 +33625,7 @@ static int unixShmMap(
         pShmNode->apRegion, nReqRegion*sizeof(char *)
     );
     if( !apNew ){
-      rc = SQLITE_IOERR_NOMEM;
+      rc = SQLITE_IOERR_NOMEM_BKPT;
       goto shmpage_out;
     }
     pShmNode->apRegion = apNew;
@@ -31828,7 +33645,7 @@ static int unixShmMap(
       }else{
         pMem = sqlite3_malloc64(szRegion);
         if( pMem==0 ){
-          rc = SQLITE_NOMEM;
+          rc = SQLITE_NOMEM_BKPT;
           goto shmpage_out;
         }
         memset(pMem, 0, szRegion);
@@ -32619,7 +34436,7 @@ static int fillInUnixFile(
   pNew->pId = vxworksFindFileId(zFilename);
   if( pNew->pId==0 ){
     ctrlFlags |= UNIXFILE_NOLOCK;
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }
 #endif
 
@@ -32675,7 +34492,7 @@ static int fillInUnixFile(
     afpLockingContext *pCtx;
     pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
     if( pCtx==0 ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }else{
       /* NB: zFilename exists and remains valid until the file is closed
       ** according to requirement F11141.  So we do not need to make a
@@ -32705,7 +34522,7 @@ static int fillInUnixFile(
     nFilename = (int)strlen(zFilename) + 6;
     zLockFile = (char *)sqlite3_malloc64(nFilename);
     if( zLockFile==0 ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }else{
       sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
     }
@@ -32728,7 +34545,7 @@ static int fillInUnixFile(
         if( zSemName[n]=='/' ) zSemName[n] = '_';
       pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
       if( pNew->pInode->pSem == SEM_FAILED ){
-        rc = SQLITE_NOMEM;
+        rc = SQLITE_NOMEM_BKPT;
         pNew->pInode->aSemName[0] = '\0';
       }
     }
@@ -32779,7 +34596,7 @@ static const char *unixTempFileDir(void){
      "/tmp",
      "."
   };
-  unsigned int i;
+  unsigned int i = 0;
   struct stat buf;
   const char *zDir = sqlite3_temp_directory;
 
@@ -32787,14 +34604,18 @@ static const char *unixTempFileDir(void){
   if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
   if( !azDirs[3] ) azDirs[2] = getenv("TMP");
   if( !azDirs[4] ) azDirs[3] = getenv("TEMP");
-  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
-    if( zDir==0 ) continue;
-    if( osStat(zDir, &buf) ) continue;
-    if( !S_ISDIR(buf.st_mode) ) continue;
-    if( osAccess(zDir, 07) ) continue;
-    break;
+  while(1){
+    if( zDir!=0
+     && osStat(zDir, &buf)==0
+     && S_ISDIR(buf.st_mode)
+     && osAccess(zDir, 03)==0
+    ){
+      return zDir;
+    }
+    if( i>=sizeof(azDirs)/sizeof(azDirs[0]) ) break;
+    zDir = azDirs[i++];
   }
-  return zDir;
+  return 0;
 }
 
 /*
@@ -32810,9 +34631,11 @@ static int unixGetTempname(int nBuf, char *zBuf){
   ** using the io-error infrastructure to test that SQLite handles this
   ** function failing. 
   */
+  zBuf[0] = 0;
   SimulateIOError( return SQLITE_IOERR );
 
   zDir = unixTempFileDir();
+  if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
   do{
     u64 r;
     sqlite3_randomness(sizeof(r), &r);
@@ -33082,7 +34905,7 @@ static int unixOpen(
     }else{
       pUnused = sqlite3_malloc64(sizeof(*pUnused));
       if( !pUnused ){
-        return SQLITE_NOMEM;
+        return SQLITE_NOMEM_BKPT;
       }
     }
     p->pUnused = pUnused;
@@ -33168,7 +34991,7 @@ static int unixOpen(
     zPath = sqlite3_mprintf("%s", zName);
     if( zPath==0 ){
       robust_close(p, fd, __LINE__);
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
 #else
     osUnlink(zName);
@@ -33179,9 +35002,6 @@ static int unixOpen(
     p->openFlags = openFlags;
   }
 #endif
-
-  noLock = eType!=SQLITE_OPEN_MAIN_DB;
-
   
 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
   if( fstatfs(fd, &fsInfo) == -1 ){
@@ -33200,6 +35020,7 @@ static int unixOpen(
   /* Set up appropriate ctrlFlags */
   if( isDelete )                ctrlFlags |= UNIXFILE_DELETE;
   if( isReadonly )              ctrlFlags |= UNIXFILE_RDONLY;
+  noLock = eType!=SQLITE_OPEN_MAIN_DB;
   if( noLock )                  ctrlFlags |= UNIXFILE_NOLOCK;
   if( syncDir )                 ctrlFlags |= UNIXFILE_DIRSYNC;
   if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
@@ -33400,7 +35221,7 @@ static int unixFullPathname(
     if( bLink ){
       if( zDel==0 ){
         zDel = sqlite3_malloc(nOut);
-        if( zDel==0 ) rc = SQLITE_NOMEM;
+        if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
       }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
         rc = SQLITE_CANTOPEN_BKPT;
       }
@@ -33638,23 +35459,18 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
 # define unixCurrentTime 0
 #endif
 
-#ifndef SQLITE_OMIT_DEPRECATED
 /*
-** We added the xGetLastError() method with the intention of providing
-** better low-level error messages when operating-system problems come up
-** during SQLite operation.  But so far, none of that has been implemented
-** in the core.  So this routine is never called.  For now, it is merely
-** a place-holder.
+** The xGetLastError() method is designed to return a better
+** low-level error message when operating-system problems come up
+** during SQLite operation.  Only the integer return code is currently
+** used.
 */
 static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
   UNUSED_PARAMETER(NotUsed);
   UNUSED_PARAMETER(NotUsed2);
   UNUSED_PARAMETER(NotUsed3);
-  return 0;
+  return errno;
 }
-#else
-# define unixGetLastError 0
-#endif
 
 
 /*
@@ -33944,7 +35760,7 @@ static int proxyCreateUnixFile(
   }else{
     pUnused = sqlite3_malloc64(sizeof(*pUnused));
     if( !pUnused ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
   }
   if( fd<0 ){
@@ -33977,7 +35793,7 @@ static int proxyCreateUnixFile(
   
   pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
   if( pNew==NULL ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
     goto end_create_proxy;
   }
   memset(pNew, 0, sizeof(unixFile));
@@ -34390,7 +36206,7 @@ static int proxyTakeConch(unixFile *pFile){
         if( tempLockPath ){
           pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
           if( !pCtx->lockProxyPath ){
-            rc = SQLITE_NOMEM;
+            rc = SQLITE_NOMEM_BKPT;
           }
         }
       }
@@ -34455,7 +36271,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
   ** the name of the original database file. */  
   *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
   if( conchPath==0 ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   memcpy(conchPath, dbPath, len+1);
   
@@ -34571,7 +36387,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
 
   pCtx = sqlite3_malloc64( sizeof(*pCtx) );
   if( pCtx==0 ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   memset(pCtx, 0, sizeof(*pCtx));
 
@@ -34607,7 +36423,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
   if( rc==SQLITE_OK ){
     pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
     if( pCtx->dbPath==NULL ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }
   }
   if( rc==SQLITE_OK ){
@@ -35518,10 +37334,22 @@ struct winFile {
 #endif
 
 /*
+ * This is cache size used in the calculation of the initial size of the
+ * Win32-specific heap.  It cannot be negative.
+ */
+#ifndef SQLITE_WIN32_CACHE_SIZE
+#  if SQLITE_DEFAULT_CACHE_SIZE>=0
+#    define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
+#  else
+#    define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
+#  endif
+#endif
+
+/*
  * The initial size of the Win32-specific heap.  This value may be zero.
  */
 #ifndef SQLITE_WIN32_HEAP_INIT_SIZE
-#  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
+#  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
                                        (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
 #endif
 
@@ -36395,7 +38223,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
     if( lastErrno==NO_ERROR ){
       sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
                   (void*)hHeap);
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }else{
       sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
                   osGetLastError(), (void*)hHeap);
@@ -36421,8 +38249,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
   int rc;
   MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
   MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
-  MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
-  MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
+  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
+  MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
   sqlite3_mutex_enter(pMaster);
   sqlite3_mutex_enter(pMem);
   winMemAssertMagic();
@@ -36467,6 +38295,12 @@ SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int n
   int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
   if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
   assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !zBuf ){
+    (void)SQLITE_MISUSE_BKPT;
+    return;
+  }
+#endif
 #if defined(SQLITE_WIN32_HAS_ANSI)
   if( nMin>0 ){
     memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
@@ -36712,7 +38546,7 @@ static int winMemInit(void *pAppData){
           "failed to HeapCreate (%lu), flags=%lu, initSize=%lu, maxSize=%u",
           osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
           dwMaximumSize);
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     pWinMemData->bOwned = TRUE;
     assert( pWinMemData->bOwned );
@@ -36722,7 +38556,7 @@ static int winMemInit(void *pAppData){
   if( !pWinMemData->hHeap ){
     sqlite3_log(SQLITE_NOMEM,
         "failed to GetProcessHeap (%lu)", osGetLastError());
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   pWinMemData->bOwned = FALSE;
   assert( !pWinMemData->bOwned );
@@ -36789,147 +38623,244 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
 #endif /* SQLITE_WIN32_MALLOC */
 
 /*
-** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
+** Convert a UTF-8 string to Microsoft Unicode.
 **
-** Space to hold the returned string is obtained from malloc.
+** Space to hold the returned string is obtained from sqlite3_malloc().
 */
-static LPWSTR winUtf8ToUnicode(const char *zFilename){
+static LPWSTR winUtf8ToUnicode(const char *zText){
   int nChar;
-  LPWSTR zWideFilename;
+  LPWSTR zWideText;
 
-  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
+  nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
   if( nChar==0 ){
     return 0;
   }
-  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
-  if( zWideFilename==0 ){
+  zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) );
+  if( zWideText==0 ){
     return 0;
   }
-  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
+  nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
                                 nChar);
   if( nChar==0 ){
-    sqlite3_free(zWideFilename);
-    zWideFilename = 0;
+    sqlite3_free(zWideText);
+    zWideText = 0;
   }
-  return zWideFilename;
+  return zWideText;
 }
 
 /*
-** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
-** obtained from sqlite3_malloc().
+** Convert a Microsoft Unicode string to UTF-8.
+**
+** Space to hold the returned string is obtained from sqlite3_malloc().
 */
-static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
+static char *winUnicodeToUtf8(LPCWSTR zWideText){
   int nByte;
-  char *zFilename;
+  char *zText;
 
-  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
+  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
   if( nByte == 0 ){
     return 0;
   }
-  zFilename = sqlite3MallocZero( nByte );
-  if( zFilename==0 ){
+  zText = sqlite3MallocZero( nByte );
+  if( zText==0 ){
     return 0;
   }
-  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
+  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
                                 0, 0);
   if( nByte == 0 ){
-    sqlite3_free(zFilename);
-    zFilename = 0;
+    sqlite3_free(zText);
+    zText = 0;
   }
-  return zFilename;
+  return zText;
 }
 
 /*
-** Convert an ANSI string to Microsoft Unicode, based on the
-** current codepage settings for file apis.
+** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM
+** code page.
 **
-** Space to hold the returned string is obtained
-** from sqlite3_malloc.
+** Space to hold the returned string is obtained from sqlite3_malloc().
 */
-static LPWSTR winMbcsToUnicode(const char *zFilename){
+static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){
   int nByte;
-  LPWSTR zMbcsFilename;
-  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
+  LPWSTR zMbcsText;
+  int codepage = useAnsi ? CP_ACP : CP_OEMCP;
 
-  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
+  nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL,
                                 0)*sizeof(WCHAR);
   if( nByte==0 ){
     return 0;
   }
-  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
-  if( zMbcsFilename==0 ){
+  zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) );
+  if( zMbcsText==0 ){
     return 0;
   }
-  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
+  nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText,
                                 nByte);
   if( nByte==0 ){
-    sqlite3_free(zMbcsFilename);
-    zMbcsFilename = 0;
+    sqlite3_free(zMbcsText);
+    zMbcsText = 0;
   }
-  return zMbcsFilename;
+  return zMbcsText;
 }
 
 /*
-** Convert Microsoft Unicode to multi-byte character string, based on the
-** user's ANSI codepage.
+** Convert a Microsoft Unicode string to a multi-byte character string,
+** using the ANSI or OEM code page.
 **
-** Space to hold the returned string is obtained from
-** sqlite3_malloc().
+** Space to hold the returned string is obtained from sqlite3_malloc().
 */
-static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
+static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){
   int nByte;
-  char *zFilename;
-  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
+  char *zText;
+  int codepage = useAnsi ? CP_ACP : CP_OEMCP;
 
-  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
+  nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0);
   if( nByte == 0 ){
     return 0;
   }
-  zFilename = sqlite3MallocZero( nByte );
-  if( zFilename==0 ){
+  zText = sqlite3MallocZero( nByte );
+  if( zText==0 ){
     return 0;
   }
-  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
+  nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText,
                                 nByte, 0, 0);
   if( nByte == 0 ){
-    sqlite3_free(zFilename);
-    zFilename = 0;
+    sqlite3_free(zText);
+    zText = 0;
   }
-  return zFilename;
+  return zText;
 }
 
 /*
-** Convert multibyte character string to UTF-8.  Space to hold the
-** returned string is obtained from sqlite3_malloc().
+** Convert a multi-byte character string to UTF-8.
+**
+** Space to hold the returned string is obtained from sqlite3_malloc().
 */
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
-  char *zFilenameUtf8;
+static char *winMbcsToUtf8(const char *zText, int useAnsi){
+  char *zTextUtf8;
   LPWSTR zTmpWide;
 
-  zTmpWide = winMbcsToUnicode(zFilename);
+  zTmpWide = winMbcsToUnicode(zText, useAnsi);
   if( zTmpWide==0 ){
     return 0;
   }
-  zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
+  zTextUtf8 = winUnicodeToUtf8(zTmpWide);
   sqlite3_free(zTmpWide);
-  return zFilenameUtf8;
+  return zTextUtf8;
 }
 
 /*
-** Convert UTF-8 to multibyte character string.  Space to hold the
-** returned string is obtained from sqlite3_malloc().
+** Convert a UTF-8 string to a multi-byte character string.
+**
+** Space to hold the returned string is obtained from sqlite3_malloc().
 */
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
-  char *zFilenameMbcs;
+static char *winUtf8ToMbcs(const char *zText, int useAnsi){
+  char *zTextMbcs;
   LPWSTR zTmpWide;
 
-  zTmpWide = winUtf8ToUnicode(zFilename);
+  zTmpWide = winUtf8ToUnicode(zText);
   if( zTmpWide==0 ){
     return 0;
   }
-  zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
+  zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi);
   sqlite3_free(zTmpWide);
-  return zFilenameMbcs;
+  return zTextMbcs;
+}
+
+/*
+** This is a public wrapper for the winUtf8ToUnicode() function.
+*/
+SQLITE_API LPWSTR SQLITE_STDCALL sqlite3_win32_utf8_to_unicode(const char *zText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !zText ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return winUtf8ToUnicode(zText);
+}
+
+/*
+** This is a public wrapper for the winUnicodeToUtf8() function.
+*/
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !zWideText ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return winUnicodeToUtf8(zWideText);
+}
+
+/*
+** This is a public wrapper for the winMbcsToUtf8() function.
+*/
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !zText ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return winMbcsToUtf8(zText, osAreFileApisANSI());
+}
+
+/*
+** This is a public wrapper for the winMbcsToUtf8() function.
+*/
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !zText ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return winMbcsToUtf8(zText, useAnsi);
+}
+
+/*
+** This is a public wrapper for the winUtf8ToMbcs() function.
+*/
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !zText ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return winUtf8ToMbcs(zText, osAreFileApisANSI());
+}
+
+/*
+** This is a public wrapper for the winUtf8ToMbcs() function.
+*/
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !zText ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return winUtf8ToMbcs(zText, useAnsi);
 }
 
 /*
@@ -36959,7 +38890,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zV
     if( zValue && zValue[0] ){
       zValueUtf8 = winUnicodeToUtf8(zValue);
       if ( zValueUtf8==0 ){
-        return SQLITE_NOMEM;
+        return SQLITE_NOMEM_BKPT;
       }
     }
     sqlite3_free(*ppDirectory);
@@ -37031,7 +38962,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
     if( dwLen > 0 ){
       /* allocate a buffer and convert to UTF8 */
       sqlite3BeginBenignMalloc();
-      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
+      zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
       sqlite3EndBenignMalloc();
       /* free the system buffer allocated by FormatMessage */
       osLocalFree(zTemp);
@@ -37173,16 +39104,17 @@ static void winLogIoerr(int nRetry, int lineno){
   }
 }
 
-#if SQLITE_OS_WINCE
-/*************************************************************************
-** This section contains code for WinCE only.
+/*
+** This #if does not rely on the SQLITE_OS_WINCE define because the
+** corresponding section in "date.c" cannot use it.
 */
-#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
+#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
+    (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
 /*
-** The MSVC CRT on Windows CE may not have a localtime() function.  So
-** create a substitute.
+** The MSVC CRT on Windows CE may not have a localtime() function.
+** So define a substitute.
 */
-/* #include <time.h> */
+/* #  include <time.h> */
 struct tm *__cdecl localtime(const time_t *t)
 {
   static struct tm y;
@@ -37206,6 +39138,10 @@ struct tm *__cdecl localtime(const time_t *t)
 }
 #endif
 
+#if SQLITE_OS_WINCE
+/*************************************************************************
+** This section contains code for WinCE only.
+*/
 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
 
 /*
@@ -37236,7 +39172,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
   zName = winUtf8ToUnicode(zFilename);
   if( zName==0 ){
     /* out of memory */
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
 
   /* Initialize the local lockdata */
@@ -38219,9 +40155,8 @@ static int winLock(sqlite3_file *id, int locktype){
   ** the PENDING_LOCK byte is temporary.
   */
   newLocktype = pFile->locktype;
-  if(   (pFile->locktype==NO_LOCK)
-     || (   (locktype==EXCLUSIVE_LOCK)
-         && (pFile->locktype==RESERVED_LOCK))
+  if( pFile->locktype==NO_LOCK
+   || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
   ){
     int cnt = 3;
     while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
@@ -38427,7 +40362,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
       return SQLITE_OK;
     }
-    case SQLITE_LAST_ERRNO: {
+    case SQLITE_FCNTL_LAST_ERRNO: {
       *(int*)pArg = (int)pFile->lastErrno;
       OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
       return SQLITE_OK;
@@ -38785,12 +40720,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
   ** allocate space for a new winShmNode and filename.
   */
   p = sqlite3MallocZero( sizeof(*p) );
-  if( p==0 ) return SQLITE_IOERR_NOMEM;
+  if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
   nName = sqlite3Strlen30(pDbFd->zPath);
   pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
   if( pNew==0 ){
     sqlite3_free(p);
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
   pNew->zFilename = (char*)&pNew[1];
   sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
@@ -38815,10 +40750,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
     pShmNode->pNext = winShmNodeList;
     winShmNodeList = pShmNode;
 
-    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-    if( pShmNode->mutex==0 ){
-      rc = SQLITE_IOERR_NOMEM;
-      goto shm_open_err;
+    if( sqlite3GlobalConfig.bCoreMutex ){
+      pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+      if( pShmNode->mutex==0 ){
+        rc = SQLITE_IOERR_NOMEM_BKPT;
+        goto shm_open_err;
+      }
     }
 
     rc = winOpen(pDbFd->pVfs,
@@ -39122,7 +41059,7 @@ static int winShmMap(
         pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
     );
     if( !apNew ){
-      rc = SQLITE_IOERR_NOMEM;
+      rc = SQLITE_IOERR_NOMEM_BKPT;
       goto shmpage_out;
     }
     pShmNode->aRegion = apNew;
@@ -39476,7 +41413,7 @@ static char *winConvertToUtf8Filename(const void *zFilename){
   }
 #ifdef SQLITE_WIN32_HAS_ANSI
   else{
-    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
+    zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
   }
 #endif
   /* caller will handle out of memory */
@@ -39525,7 +41462,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){
   }
 #ifdef SQLITE_WIN32_HAS_ANSI
   else{
-    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
+    zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
   }
 #endif
   /* caller will handle out of memory */
@@ -39580,7 +41517,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
   zBuf = sqlite3MallocZero( nBuf );
   if( !zBuf ){
     OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
 
   /* Figure out the effective temporary directory.  First, check if one
@@ -39638,7 +41575,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
         if( !zConverted ){
           sqlite3_free(zBuf);
           OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-          return SQLITE_IOERR_NOMEM;
+          return SQLITE_IOERR_NOMEM_BKPT;
         }
         if( winIsDir(zConverted) ){
           sqlite3_snprintf(nMax, zBuf, "%s", zDir);
@@ -39651,7 +41588,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
         if( !zConverted ){
           sqlite3_free(zBuf);
           OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-          return SQLITE_IOERR_NOMEM;
+          return SQLITE_IOERR_NOMEM_BKPT;
         }
         if( cygwin_conv_path(
                 osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
@@ -39672,7 +41609,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
             sqlite3_free(zConverted);
             sqlite3_free(zBuf);
             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-            return SQLITE_IOERR_NOMEM;
+            return SQLITE_IOERR_NOMEM_BKPT;
           }
           sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
           sqlite3_free(zUtf8);
@@ -39690,7 +41627,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
     if( !zWidePath ){
       sqlite3_free(zBuf);
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
     if( osGetTempPathW(nMax, zWidePath)==0 ){
       sqlite3_free(zWidePath);
@@ -39708,7 +41645,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
       sqlite3_free(zWidePath);
       sqlite3_free(zBuf);
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
   }
 #ifdef SQLITE_WIN32_HAS_ANSI
@@ -39718,7 +41655,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
     if( !zMbcsPath ){
       sqlite3_free(zBuf);
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
     if( osGetTempPathA(nMax, zMbcsPath)==0 ){
       sqlite3_free(zBuf);
@@ -39726,14 +41663,14 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
       return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
                          "winGetTempname3", 0);
     }
-    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
+    zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI());
     if( zUtf8 ){
       sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
       sqlite3_free(zUtf8);
     }else{
       sqlite3_free(zBuf);
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
   }
 #endif /* SQLITE_WIN32_HAS_ANSI */
@@ -39925,7 +41862,7 @@ static int winOpen(
   if( zConverted==0 ){
     sqlite3_free(zTmpname);
     OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
 
   if( winIsDir(zConverted) ){
@@ -40125,7 +42062,7 @@ static int winDelete(
   zConverted = winConvertFromUtf8Filename(zFilename);
   if( zConverted==0 ){
     OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
   if( osIsNT() ){
     do {
@@ -40233,7 +42170,7 @@ static int winAccess(
   zConverted = winConvertFromUtf8Filename(zFilename);
   if( zConverted==0 ){
     OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
   if( osIsNT() ){
     int cnt = 0;
@@ -40360,7 +42297,7 @@ static int winFullPathname(
     */
     char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
     if( !zOut ){
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
     if( cygwin_conv_path(
             (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
@@ -40372,7 +42309,7 @@ static int winFullPathname(
       char *zUtf8 = winConvertToUtf8Filename(zOut);
       if( !zUtf8 ){
         sqlite3_free(zOut);
-        return SQLITE_IOERR_NOMEM;
+        return SQLITE_IOERR_NOMEM_BKPT;
       }
       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
                        sqlite3_data_directory, winGetDirSep(), zUtf8);
@@ -40382,7 +42319,7 @@ static int winFullPathname(
   }else{
     char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
     if( !zOut ){
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
     if( cygwin_conv_path(
             (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
@@ -40394,7 +42331,7 @@ static int winFullPathname(
       char *zUtf8 = winConvertToUtf8Filename(zOut);
       if( !zUtf8 ){
         sqlite3_free(zOut);
-        return SQLITE_IOERR_NOMEM;
+        return SQLITE_IOERR_NOMEM_BKPT;
       }
       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
       sqlite3_free(zUtf8);
@@ -40454,7 +42391,7 @@ static int winFullPathname(
   }
   zConverted = winConvertFromUtf8Filename(zRelative);
   if( zConverted==0 ){
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
   if( osIsNT() ){
     LPWSTR zTemp;
@@ -40468,7 +42405,7 @@ static int winFullPathname(
     zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
     if( zTemp==0 ){
       sqlite3_free(zConverted);
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
     nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
     if( nByte==0 ){
@@ -40494,7 +42431,7 @@ static int winFullPathname(
     zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
     if( zTemp==0 ){
       sqlite3_free(zConverted);
-      return SQLITE_IOERR_NOMEM;
+      return SQLITE_IOERR_NOMEM_BKPT;
     }
     nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
     if( nByte==0 ){
@@ -40504,7 +42441,7 @@ static int winFullPathname(
                          "winFullPathname4", zRelative);
     }
     sqlite3_free(zConverted);
-    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
+    zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
     sqlite3_free(zTemp);
   }
 #endif
@@ -40513,7 +42450,7 @@ static int winFullPathname(
     sqlite3_free(zOut);
     return SQLITE_OK;
   }else{
-    return SQLITE_IOERR_NOMEM;
+    return SQLITE_IOERR_NOMEM_BKPT;
   }
 #endif
 }
@@ -40588,82 +42525,101 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
   #define winDlClose 0
 #endif
 
+/* State information for the randomness gatherer. */
+typedef struct EntropyGatherer EntropyGatherer;
+struct EntropyGatherer {
+  unsigned char *a;   /* Gather entropy into this buffer */
+  int na;             /* Size of a[] in bytes */
+  int i;              /* XOR next input into a[i] */
+  int nXor;           /* Number of XOR operations done */
+};
+
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
+/* Mix sz bytes of entropy into p. */
+static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
+  int j, k;
+  for(j=0, k=p->i; j<sz; j++){
+    p->a[k++] ^= x[j];
+    if( k>=p->na ) k = 0;
+  }
+  p->i = k;
+  p->nXor += sz;
+}
+#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */
 
 /*
 ** Write up to nBuf bytes of randomness into zBuf.
 */
 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-  int n = 0;
-  UNUSED_PARAMETER(pVfs);
 #if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
-  n = nBuf;
+  UNUSED_PARAMETER(pVfs);
   memset(zBuf, 0, nBuf);
+  return nBuf;
 #else
-  if( (int)sizeof(SYSTEMTIME)<=nBuf-n ){
+  EntropyGatherer e;
+  UNUSED_PARAMETER(pVfs);
+  memset(zBuf, 0, nBuf);
+#ifdef HAVE_RAND_S
+  rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */
+#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
+  e.a = (unsigned char*)zBuf;
+  e.na = nBuf;
+  e.nXor = 0;
+  e.i = 0;
+  {
     SYSTEMTIME x;
     osGetSystemTime(&x);
-    memcpy(&zBuf[n], &x, sizeof(x));
-    n += sizeof(x);
+    xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
   }
-  if( (int)sizeof(DWORD)<=nBuf-n ){
+  {
     DWORD pid = osGetCurrentProcessId();
-    memcpy(&zBuf[n], &pid, sizeof(pid));
-    n += sizeof(pid);
+    xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
   }
 #if SQLITE_OS_WINRT
-  if( (int)sizeof(ULONGLONG)<=nBuf-n ){
+  {
     ULONGLONG cnt = osGetTickCount64();
-    memcpy(&zBuf[n], &cnt, sizeof(cnt));
-    n += sizeof(cnt);
+    xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG));
   }
 #else
-  if( (int)sizeof(DWORD)<=nBuf-n ){
+  {
     DWORD cnt = osGetTickCount();
-    memcpy(&zBuf[n], &cnt, sizeof(cnt));
-    n += sizeof(cnt);
+    xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD));
   }
-#endif
-  if( (int)sizeof(LARGE_INTEGER)<=nBuf-n ){
+#endif /* SQLITE_OS_WINRT */
+  {
     LARGE_INTEGER i;
     osQueryPerformanceCounter(&i);
-    memcpy(&zBuf[n], &i, sizeof(i));
-    n += sizeof(i);
+    xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER));
   }
 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-  if( (int)sizeof(UUID)<=nBuf-n ){
+  {
     UUID id;
 #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_WIN32_USE_UUID)
     static HMODULE module = 0;
-    if( module == (HMODULE)-1 ){
-      return n;
-    }else if( !module ){
+    if( !module && module != (HMODULE)-1 ){
       module = osLoadLibraryW(L"RPCRT4.DLL");
-      if( !module){
+      if( !module ){
         module = (HMODULE)-1;
-        return n;
+      }else{
+        aSyscall[77].pCurrent = (SYSCALL) osGetProcAddressA(module, "UuidCreate");
+        aSyscall[78].pCurrent = (SYSCALL) osGetProcAddressA(module, "UuidCreateSequential");
       }
-      aSyscall[77].pCurrent = (SYSCALL) osGetProcAddressA(module, "UuidCreate");
-      aSyscall[78].pCurrent = (SYSCALL) osGetProcAddressA(module, "UuidCreateSequential");
     }
 #endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */
-    if( !osUuidCreate ){
-       return n;
+    if( osUuidCreate ){
+      memset(&id, 0, sizeof(UUID));
+      osUuidCreate(&id);
+      xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
+    }
+    if( osUuidCreateSequential ){
+      memset(&id, 0, sizeof(UUID));
+      osUuidCreateSequential(&id);
+      xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
     }
-    memset(&id, 0, sizeof(UUID));
-    osUuidCreate(&id);
-    memcpy(&zBuf[n], &id, sizeof(UUID));
-    n += sizeof(UUID);
-  }
-  if( osUuidCreateSequential && (int)sizeof(UUID)<=nBuf-n ){
-    UUID id;
-    memset(&id, 0, sizeof(UUID));
-    osUuidCreateSequential(&id);
-    memcpy(&zBuf[n], &id, sizeof(UUID));
-    n += sizeof(UUID);
   }
-#endif
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
-  return n;
+#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */
+  return e.nXor>nBuf ? nBuf : e.nXor;
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */
 }
 
 
@@ -40779,8 +42735,10 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
 ** sqlite3_errmsg(), possibly making IO errors easier to debug.
 */
 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+  DWORD e = osGetLastError();
   UNUSED_PARAMETER(pVfs);
-  return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
+  if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf);
+  return e;
 }
 
 /*
@@ -41054,7 +43012,7 @@ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
     i = i%p->iDivisor;
     if( p->u.apSub[bin]==0 ){
       p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
-      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
+      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT;
     }
     p = p->u.apSub[bin];
   }
@@ -41089,7 +43047,7 @@ bitvec_set_rehash:
     int rc;
     u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
     if( aiValues==0 ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }else{
       memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
       memset(p->u.apSub, 0, sizeof(p->u.apSub));
@@ -41305,7 +43263,29 @@ bitvec_end:
 /* #include "sqliteInt.h" */
 
 /*
-** A complete page cache is an instance of this structure.
+** A complete page cache is an instance of this structure.  Every
+** entry in the cache holds a single page of the database file.  The
+** btree layer only operates on the cached copy of the database pages.
+**
+** A page cache entry is "clean" if it exactly matches what is currently
+** on disk.  A page is "dirty" if it has been modified and needs to be
+** persisted to disk.
+**
+** pDirty, pDirtyTail, pSynced:
+**   All dirty pages are linked into the doubly linked list using
+**   PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order
+**   such that p was added to the list more recently than p->pDirtyNext.
+**   PCache.pDirty points to the first (newest) element in the list and
+**   pDirtyTail to the last (oldest).
+**
+**   The PCache.pSynced variable is used to optimize searching for a dirty
+**   page to eject from the cache mid-transaction. It is better to eject
+**   a page that does not require a journal sync than one that does. 
+**   Therefore, pSynced is maintained to that it *almost* always points
+**   to either the oldest page in the pDirty/pDirtyTail list that has a
+**   clear PGHDR_NEED_SYNC flag or to a page that is older than this one
+**   (so that the right page to eject can be found by following pDirtyPrev
+**   pointers).
 */
 struct PCache {
   PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
@@ -41322,6 +43302,95 @@ struct PCache {
   sqlite3_pcache *pCache;             /* Pluggable cache module */
 };
 
+/********************************** Test and Debug Logic **********************/
+/*
+** Debug tracing macros.  Enable by by changing the "0" to "1" and
+** recompiling.
+**
+** When sqlite3PcacheTrace is 1, single line trace messages are issued.
+** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries
+** is displayed for many operations, resulting in a lot of output.
+*/
+#if defined(SQLITE_DEBUG) && 0
+  int sqlite3PcacheTrace = 2;       /* 0: off  1: simple  2: cache dumps */
+  int sqlite3PcacheMxDump = 9999;   /* Max cache entries for pcacheDump() */
+# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;}
+  void pcacheDump(PCache *pCache){
+    int N;
+    int i, j;
+    sqlite3_pcache_page *pLower;
+    PgHdr *pPg;
+    unsigned char *a;
+  
+    if( sqlite3PcacheTrace<2 ) return;
+    if( pCache->pCache==0 ) return;
+    N = sqlite3PcachePagecount(pCache);
+    if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump;
+    for(i=1; i<=N; i++){
+       pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0);
+       if( pLower==0 ) continue;
+       pPg = (PgHdr*)pLower->pExtra;
+       printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
+       a = (unsigned char *)pLower->pBuf;
+       for(j=0; j<12; j++) printf("%02x", a[j]);
+       printf("\n");
+       if( pPg->pPage==0 ){
+         sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0);
+       }
+    }
+  }
+  #else
+# define pcacheTrace(X)
+# define pcacheDump(X)
+#endif
+
+/*
+** Check invariants on a PgHdr entry.  Return true if everything is OK.
+** Return false if any invariant is violated.
+**
+** This routine is for use inside of assert() statements only.  For
+** example:
+**
+**          assert( sqlite3PcachePageSanity(pPg) );
+*/
+#if SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){
+  PCache *pCache;
+  assert( pPg!=0 );
+  assert( pPg->pgno>0 );    /* Page number is 1 or more */
+  pCache = pPg->pCache;
+  assert( pCache!=0 );      /* Every page has an associated PCache */
+  if( pPg->flags & PGHDR_CLEAN ){
+    assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */
+    assert( pCache->pDirty!=pPg );          /* CLEAN pages not on dirty list */
+    assert( pCache->pDirtyTail!=pPg );
+  }
+  /* WRITEABLE pages must also be DIRTY */
+  if( pPg->flags & PGHDR_WRITEABLE ){
+    assert( pPg->flags & PGHDR_DIRTY );     /* WRITEABLE implies DIRTY */
+  }
+  /* NEED_SYNC can be set independently of WRITEABLE.  This can happen,
+  ** for example, when using the sqlite3PagerDontWrite() optimization:
+  **    (1)  Page X is journalled, and gets WRITEABLE and NEED_SEEK.
+  **    (2)  Page X moved to freelist, WRITEABLE is cleared
+  **    (3)  Page X reused, WRITEABLE is set again
+  ** If NEED_SYNC had been cleared in step 2, then it would not be reset
+  ** in step 3, and page might be written into the database without first
+  ** syncing the rollback journal, which might cause corruption on a power
+  ** loss.
+  **
+  ** Another example is when the database page size is smaller than the
+  ** disk sector size.  When any page of a sector is journalled, all pages
+  ** in that sector are marked NEED_SYNC even if they are still CLEAN, just
+  ** in case they are later modified, since all pages in the same sector
+  ** must be journalled and synced before any of those pages can be safely
+  ** written.
+  */
+  return 1;
+}
+#endif /* SQLITE_DEBUG */
+
+
 /********************************** Linked List Management ********************/
 
 /* Allowed values for second argument to pcacheManageDirtyList() */
@@ -41338,17 +43407,16 @@ struct PCache {
 static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
   PCache *p = pPage->pCache;
 
+  pcacheTrace(("%p.DIRTYLIST.%s %d\n", p,
+                addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT",
+                pPage->pgno));
   if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
     assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
     assert( pPage->pDirtyPrev || pPage==p->pDirty );
   
     /* Update the PCache1.pSynced variable if necessary. */
     if( p->pSynced==pPage ){
-      PgHdr *pSynced = pPage->pDirtyPrev;
-      while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
-        pSynced = pSynced->pDirtyPrev;
-      }
-      p->pSynced = pSynced;
+      p->pSynced = pPage->pDirtyPrev;
     }
   
     if( pPage->pDirtyNext ){
@@ -41360,10 +43428,15 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
     if( pPage->pDirtyPrev ){
       pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
     }else{
+      /* If there are now no dirty pages in the cache, set eCreate to 2. 
+      ** This is an optimization that allows sqlite3PcacheFetch() to skip
+      ** searching for a dirty page to eject from the cache when it might
+      ** otherwise have to.  */
       assert( pPage==p->pDirty );
       p->pDirty = pPage->pDirtyNext;
-      if( p->pDirty==0 && p->bPurgeable ){
-        assert( p->eCreate==1 );
+      assert( p->bPurgeable || p->eCreate==2 );
+      if( p->pDirty==0 ){         /*OPTIMIZATION-IF-TRUE*/
+        assert( p->bPurgeable==0 || p->eCreate==1 );
         p->eCreate = 2;
       }
     }
@@ -41385,10 +43458,19 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
       }
     }
     p->pDirty = pPage;
-    if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
+
+    /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set
+    ** pSynced to point to it. Checking the NEED_SYNC flag is an 
+    ** optimization, as if pSynced points to a page with the NEED_SYNC
+    ** flag set sqlite3PcacheFetchStress() searches through all newer 
+    ** entries of the dirty-list for a page with NEED_SYNC clear anyway.  */
+    if( !p->pSynced 
+     && 0==(pPage->flags&PGHDR_NEED_SYNC)   /*OPTIMIZATION-IF-FALSE*/
+    ){
       p->pSynced = pPage;
     }
   }
+  pcacheDump(p);
 }
 
 /*
@@ -41397,7 +43479,9 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
 */
 static void pcacheUnpin(PgHdr *p){
   if( p->pCache->bPurgeable ){
+    pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno));
     sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
+    pcacheDump(p->pCache);
   }
 }
 
@@ -41467,6 +43551,7 @@ SQLITE_PRIVATE int sqlite3PcacheOpen(
   p->pStress = pStress;
   p->szCache = 100;
   p->szSpill = 1;
+  pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable));
   return sqlite3PcacheSetPageSize(p, szPage);
 }
 
@@ -41482,13 +43567,14 @@ SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
                 szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
                 pCache->bPurgeable
     );
-    if( pNew==0 ) return SQLITE_NOMEM;
+    if( pNew==0 ) return SQLITE_NOMEM_BKPT;
     sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
     if( pCache->pCache ){
       sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
     }
     pCache->pCache = pNew;
     pCache->szPage = szPage;
+    pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage));
   }
   return SQLITE_OK;
 }
@@ -41523,11 +43609,13 @@ SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
   int createFlag        /* If true, create page if it does not exist already */
 ){
   int eCreate;
+  sqlite3_pcache_page *pRes;
 
   assert( pCache!=0 );
   assert( pCache->pCache!=0 );
   assert( createFlag==3 || createFlag==0 );
   assert( pgno>0 );
+  assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) );
 
   /* eCreate defines what to do if the page does not exist.
   **    0     Do not allocate a new page.  (createFlag==0)
@@ -41540,12 +43628,15 @@ SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
   assert( eCreate==0 || eCreate==1 || eCreate==2 );
   assert( createFlag==0 || pCache->eCreate==eCreate );
   assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
-  return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
+  pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
+  pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno,
+               createFlag?" create":"",pRes));
+  return pRes;
 }
 
 /*
 ** If the sqlite3PcacheFetch() routine is unable to allocate a new
-** page because new clean pages are available for reuse and the cache
+** page because no clean pages are available for reuse and the cache
 ** size limit has been reached, then this routine can be invoked to 
 ** try harder to allocate a page.  This routine might invoke the stress
 ** callback to spill dirty pages to the journal.  It will then try to
@@ -41567,7 +43658,11 @@ SQLITE_PRIVATE int sqlite3PcacheFetchStress(
     ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
     ** cleared), but if that is not possible settle for any other 
     ** unreferenced dirty page.
-    */
+    **
+    ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC
+    ** flag is currently referenced, then the following may leave pSynced
+    ** set incorrectly (pointing to other than the LRU page with NEED_SYNC
+    ** cleared). This is Ok, as pSynced is just an optimization.  */
     for(pPg=pCache->pSynced; 
         pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
         pPg=pPg->pDirtyPrev
@@ -41585,14 +43680,16 @@ SQLITE_PRIVATE int sqlite3PcacheFetchStress(
                   sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
                 numberOfCachePages(pCache));
 #endif
+      pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
       rc = pCache->xStress(pCache->pStress, pPg);
+      pcacheDump(pCache);
       if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
         return rc;
       }
     }
   }
   *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
-  return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
+  return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
 }
 
 /*
@@ -41645,6 +43742,7 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
   }
   pCache->nRefSum++;
   pPgHdr->nRef++;
+  assert( sqlite3PcachePageSanity(pPgHdr) );
   return pPgHdr;
 }
 
@@ -41658,8 +43756,11 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
   if( (--p->nRef)==0 ){
     if( p->flags&PGHDR_CLEAN ){
       pcacheUnpin(p);
-    }else if( p->pDirtyPrev!=0 ){
-      /* Move the page to the head of the dirty list. */
+    }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/
+      /* Move the page to the head of the dirty list. If p->pDirtyPrev==0,
+      ** then page p is already at the head of the dirty list and the
+      ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE
+      ** tag above.  */
       pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
     }
   }
@@ -41670,6 +43771,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
 */
 SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
   assert(p->nRef>0);
+  assert( sqlite3PcachePageSanity(p) );
   p->nRef++;
   p->pCache->nRefSum++;
 }
@@ -41681,6 +43783,7 @@ SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
 */
 SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
   assert( p->nRef==1 );
+  assert( sqlite3PcachePageSanity(p) );
   if( p->flags&PGHDR_DIRTY ){
     pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
   }
@@ -41694,13 +43797,16 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
 */
 SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
   assert( p->nRef>0 );
-  if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){
+  assert( sqlite3PcachePageSanity(p) );
+  if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){    /*OPTIMIZATION-IF-FALSE*/
     p->flags &= ~PGHDR_DONT_WRITE;
     if( p->flags & PGHDR_CLEAN ){
       p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN);
+      pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno));
       assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY );
       pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
     }
+    assert( sqlite3PcachePageSanity(p) );
   }
 }
 
@@ -41709,11 +43815,14 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
 ** make it so.
 */
 SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
-  if( (p->flags & PGHDR_DIRTY) ){
+  assert( sqlite3PcachePageSanity(p) );
+  if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){
     assert( (p->flags & PGHDR_CLEAN)==0 );
     pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
     p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
     p->flags |= PGHDR_CLEAN;
+    pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
+    assert( sqlite3PcachePageSanity(p) );
     if( p->nRef==0 ){
       pcacheUnpin(p);
     }
@@ -41725,12 +43834,25 @@ SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
 */
 SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
   PgHdr *p;
+  pcacheTrace(("%p.CLEAN-ALL\n",pCache));
   while( (p = pCache->pDirty)!=0 ){
     sqlite3PcacheMakeClean(p);
   }
 }
 
 /*
+** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
+*/
+SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){
+  PgHdr *p;
+  pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache));
+  for(p=pCache->pDirty; p; p=p->pDirtyNext){
+    p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+  }
+  pCache->pSynced = pCache->pDirtyTail;
+}
+
+/*
 ** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
 */
 SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
@@ -41748,6 +43870,8 @@ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
   PCache *pCache = p->pCache;
   assert( p->nRef>0 );
   assert( newPgno>0 );
+  assert( sqlite3PcachePageSanity(p) );
+  pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
   sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
   p->pgno = newPgno;
   if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
@@ -41768,6 +43892,7 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
   if( pCache->pCache ){
     PgHdr *p;
     PgHdr *pNext;
+    pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno));
     for(p=pCache->pDirty; p; p=pNext){
       pNext = p->pDirtyNext;
       /* This routine never gets call with a positive pgno except right
@@ -41775,7 +43900,7 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
       ** it must be that pgno==0.
       */
       assert( p->pgno>0 );
-      if( ALWAYS(p->pgno>pgno) ){
+      if( p->pgno>pgno ){
         assert( p->flags&PGHDR_DIRTY );
         sqlite3PcacheMakeClean(p);
       }
@@ -41798,6 +43923,7 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
 */
 SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
   assert( pCache->pCache!=0 );
+  pcacheTrace(("%p.CLOSE\n",pCache));
   sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
 }
 
@@ -41966,6 +44092,17 @@ SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
 */
 SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
 
+/*
+** Return the number of dirty pages currently in the cache, as a percentage
+** of the configured cache size.
+*/
+SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){
+  PgHdr *pDirty;
+  int nDirty = 0;
+  int nCache = numberOfCachePages(pCache);
+  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
+  return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
+}
 
 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
 /*
@@ -42333,7 +44470,6 @@ static void *pcache1Alloc(size_t nByte){
 ** Free an allocated buffer obtained from pcache1Alloc().
 */
 static void pcache1Free(void *p){
-  int nFreed = 0;
   if( p==0 ) return;
   if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){
     PgFreeslot *pSlot;
@@ -42350,10 +44486,13 @@ static void pcache1Free(void *p){
     assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
     sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
 #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
-    nFreed = sqlite3MallocSize(p);
-    sqlite3_mutex_enter(pcache1.mutex);
-    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
-    sqlite3_mutex_leave(pcache1.mutex);
+    {
+      int nFreed = 0;
+      nFreed = sqlite3MallocSize(p);
+      sqlite3_mutex_enter(pcache1.mutex);
+      sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
+      sqlite3_mutex_leave(pcache1.mutex);
+    }
 #endif
     sqlite3_free(p);
   }
@@ -42673,8 +44812,8 @@ static int pcache1Init(void *NotUsed){
 
 #if SQLITE_THREADSAFE
   if( sqlite3GlobalConfig.bCoreMutex ){
-    pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
-    pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
+    pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU);
+    pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM);
   }
 #endif
   if( pcache1.separateCache
@@ -43280,8 +45419,9 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
 ** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
 ** primitives are constant time.  The cost of DESTROY is O(N).
 **
-** There is an added cost of O(N) when switching between TEST and
-** SMALLEST primitives.
+** TEST and SMALLEST may not be used by the same RowSet.  This used to
+** be possible, but the feature was not used, so it was removed in order
+** to simplify the code.
 */
 /* #include "sqliteInt.h" */
 
@@ -43402,7 +45542,9 @@ SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
 */
 static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
   assert( p!=0 );
-  if( p->nFresh==0 ){
+  if( p->nFresh==0 ){  /*OPTIMIZATION-IF-FALSE*/
+    /* We could allocate a fresh RowSetEntry each time one is needed, but it
+    ** is more efficient to pull a preallocated entry from the pool */
     struct RowSetChunk *pNew;
     pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew));
     if( pNew==0 ){
@@ -43436,7 +45578,9 @@ SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
   pEntry->pRight = 0;
   pLast = p->pLast;
   if( pLast ){
-    if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
+    if( rowid<=pLast->v ){  /*OPTIMIZATION-IF-FALSE*/
+      /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags
+      ** where possible */
       p->rsFlags &= ~ROWSET_SORTED;
     }
     pLast->pRight = pEntry;
@@ -43558,23 +45702,29 @@ static struct RowSetEntry *rowSetNDeepTree(
 ){
   struct RowSetEntry *p;         /* Root of the new tree */
   struct RowSetEntry *pLeft;     /* Left subtree */
-  if( *ppList==0 ){
-    return 0;
-  }
-  if( iDepth==1 ){
+  if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/
+    /* Prevent unnecessary deep recursion when we run out of entries */
+    return 0; 
+  }
+  if( iDepth>1 ){   /*OPTIMIZATION-IF-TRUE*/
+    /* This branch causes a *balanced* tree to be generated.  A valid tree
+    ** is still generated without this branch, but the tree is wildly
+    ** unbalanced and inefficient. */
+    pLeft = rowSetNDeepTree(ppList, iDepth-1);
+    p = *ppList;
+    if( p==0 ){     /*OPTIMIZATION-IF-FALSE*/
+      /* It is safe to always return here, but the resulting tree
+      ** would be unbalanced */
+      return pLeft;
+    }
+    p->pLeft = pLeft;
+    *ppList = p->pRight;
+    p->pRight = rowSetNDeepTree(ppList, iDepth-1);
+  }else{
     p = *ppList;
     *ppList = p->pRight;
     p->pLeft = p->pRight = 0;
-    return p;
-  }
-  pLeft = rowSetNDeepTree(ppList, iDepth-1);
-  p = *ppList;
-  if( p==0 ){
-    return pLeft;
   }
-  p->pLeft = pLeft;
-  *ppList = p->pRight;
-  p->pRight = rowSetNDeepTree(ppList, iDepth-1);
   return p;
 }
 
@@ -43602,58 +45752,36 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
 }
 
 /*
-** Take all the entries on p->pEntry and on the trees in p->pForest and
-** sort them all together into one big ordered list on p->pEntry.
-**
-** This routine should only be called once in the life of a RowSet.
-*/
-static void rowSetToList(RowSet *p){
-
-  /* This routine is called only once */
-  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-
-  if( (p->rsFlags & ROWSET_SORTED)==0 ){
-    p->pEntry = rowSetEntrySort(p->pEntry);
-  }
-
-  /* While this module could theoretically support it, sqlite3RowSetNext()
-  ** is never called after sqlite3RowSetText() for the same RowSet.  So
-  ** there is never a forest to deal with.  Should this change, simply
-  ** remove the assert() and the #if 0. */
-  assert( p->pForest==0 );
-#if 0
-  while( p->pForest ){
-    struct RowSetEntry *pTree = p->pForest->pLeft;
-    if( pTree ){
-      struct RowSetEntry *pHead, *pTail;
-      rowSetTreeToList(pTree, &pHead, &pTail);
-      p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
-    }
-    p->pForest = p->pForest->pRight;
-  }
-#endif
-  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
-}
-
-/*
 ** Extract the smallest element from the RowSet.
 ** Write the element into *pRowid.  Return 1 on success.  Return
 ** 0 if the RowSet is already empty.
 **
 ** After this routine has been called, the sqlite3RowSetInsert()
-** routine may not be called again.  
+** routine may not be called again.
+**
+** This routine may not be called after sqlite3RowSetTest() has
+** been used.  Older versions of RowSet allowed that, but as the
+** capability was not used by the code generator, it was removed
+** for code economy.
 */
 SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
   assert( p!=0 );
+  assert( p->pForest==0 );  /* Cannot be used with sqlite3RowSetText() */
 
   /* Merge the forest into a single sorted list on first call */
-  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
+  if( (p->rsFlags & ROWSET_NEXT)==0 ){  /*OPTIMIZATION-IF-FALSE*/
+    if( (p->rsFlags & ROWSET_SORTED)==0 ){  /*OPTIMIZATION-IF-FALSE*/
+      p->pEntry = rowSetEntrySort(p->pEntry);
+    }
+    p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT;
+  }
 
   /* Return the next entry on the list */
   if( p->pEntry ){
     *pRowid = p->pEntry->v;
     p->pEntry = p->pEntry->pRight;
-    if( p->pEntry==0 ){
+    if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/
+      /* Free memory immediately, rather than waiting on sqlite3_finalize() */
       sqlite3RowSetClear(p);
     }
     return 1;
@@ -43676,13 +45804,15 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
   /* This routine is never called after sqlite3RowSetNext() */
   assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
 
-  /* Sort entries into the forest on the first test of a new batch 
+  /* Sort entries into the forest on the first test of a new batch.
+  ** To save unnecessary work, only do this when the batch number changes.
   */
-  if( iBatch!=pRowSet->iBatch ){
+  if( iBatch!=pRowSet->iBatch ){  /*OPTIMIZATION-IF-FALSE*/
     p = pRowSet->pEntry;
     if( p ){
       struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
-      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
+      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+        /* Only sort the current set of entiries if they need it */
         p = rowSetEntrySort(p);
       }
       for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
@@ -44312,19 +46442,6 @@ int sqlite3PagerTrace=1;  /* True to enable tracing */
 */
 #define MAX_SECTOR_SIZE 0x10000
 
-/*
-** If the option SQLITE_EXTRA_DURABLE option is set at compile-time, then
-** SQLite will do extra fsync() operations when synchronous==FULL to help
-** ensure that transactions are durable across a power failure.  Most
-** applications are happy as long as transactions are consistent across
-** a power failure, and are perfectly willing to lose the last transaction
-** in exchange for the extra performance of avoiding directory syncs.
-** And so the default SQLITE_EXTRA_DURABLE setting is off.
-*/
-#ifndef SQLITE_EXTRA_DURABLE
-# define SQLITE_EXTRA_DURABLE 0
-#endif
-
 
 /*
 ** An instance of the following structure is allocated for each active
@@ -44769,6 +46886,7 @@ static int assert_pager_state(Pager *p){
   ** state.
   */
   if( MEMDB ){
+    assert( !isOpen(p->fd) );
     assert( p->noSync );
     assert( p->journalMode==PAGER_JOURNALMODE_OFF 
          || p->journalMode==PAGER_JOURNALMODE_MEMORY 
@@ -44855,7 +46973,7 @@ static int assert_pager_state(Pager *p){
       ** back to OPEN state.
       */
       assert( pPager->errCode!=SQLITE_OK );
-      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
+      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile );
       break;
   }
 
@@ -45067,6 +47185,8 @@ static int jrnlBufferSize(Pager *pPager){
 
   return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
 }
+#else
+# define jrnlBufferSize(x) 0
 #endif
 
 /*
@@ -45227,6 +47347,7 @@ static i64 journalHdrOffset(Pager *pPager){
 static int zeroJournalHdr(Pager *pPager, int doTruncate){
   int rc = SQLITE_OK;                               /* Return code */
   assert( isOpen(pPager->jfd) );
+  assert( !sqlite3JournalIsInMemory(pPager->jfd) );
   if( pPager->journalOff ){
     const i64 iLimit = pPager->journalSizeLimit;    /* Local cache of jsl */
 
@@ -45608,7 +47729,7 @@ static void releaseAllSavepoints(Pager *pPager){
   for(ii=0; ii<pPager->nSavepoint; ii++){
     sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
   }
-  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
+  if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){
     sqlite3OsClose(pPager->sjfd);
   }
   sqlite3_free(pPager->aSavepoint);
@@ -45714,13 +47835,17 @@ static void pager_unlock(Pager *pPager){
   ** it can safely move back to PAGER_OPEN state. This happens in both
   ** normal and exclusive-locking mode.
   */
+  assert( pPager->errCode==SQLITE_OK || !MEMDB );
   if( pPager->errCode ){
-    assert( !MEMDB );
-    pager_reset(pPager);
-    pPager->changeCountDone = pPager->tempFile;
-    pPager->eState = PAGER_OPEN;
-    pPager->errCode = SQLITE_OK;
+    if( pPager->tempFile==0 ){
+      pager_reset(pPager);
+      pPager->changeCountDone = 0;
+      pPager->eState = PAGER_OPEN;
+    }else{
+      pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER);
+    }
     if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
+    pPager->errCode = SQLITE_OK;
   }
 
   pPager->journalOff = 0;
@@ -45765,6 +47890,29 @@ static int pager_error(Pager *pPager, int rc){
 static int pager_truncate(Pager *pPager, Pgno nPage);
 
 /*
+** The write transaction open on pPager is being committed (bCommit==1)
+** or rolled back (bCommit==0).
+**
+** Return TRUE if and only if all dirty pages should be flushed to disk.
+**
+** Rules:
+**
+**   *  For non-TEMP databases, always sync to disk.  This is necessary
+**      for transactions to be durable.
+**
+**   *  Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing
+**      file has been created already (via a spill on pagerStress()) and
+**      when the number of dirty pages in memory exceeds 25% of the total
+**      cache size.
+*/
+static int pagerFlushOnCommit(Pager *pPager, int bCommit){
+  if( pPager->tempFile==0 ) return 1;
+  if( !bCommit ) return 0;
+  if( !isOpen(pPager->fd) ) return 0;
+  return (sqlite3PCachePercentDirty(pPager->pPCache)>=25);
+}
+
+/*
 ** This routine ends a transaction. A transaction is usually ended by 
 ** either a COMMIT or a ROLLBACK operation. This routine may be called 
 ** after rollback of a hot-journal, or if an error occurs while opening
@@ -45846,8 +47994,8 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
     assert( !pagerUseWal(pPager) );
 
     /* Finalize the journal file. */
-    if( sqlite3IsMemJournal(pPager->jfd) ){
-      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
+    if( sqlite3JournalIsInMemory(pPager->jfd) ){
+      /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */
       sqlite3OsClose(pPager->jfd);
     }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
       if( pPager->journalOff==0 ){
@@ -45867,15 +48015,16 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
     }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
       || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
     ){
-      rc = zeroJournalHdr(pPager, hasMaster);
+      rc = zeroJournalHdr(pPager, hasMaster||pPager->tempFile);
       pPager->journalOff = 0;
     }else{
       /* This branch may be executed with Pager.journalMode==MEMORY if
       ** a hot-journal was just rolled back. In this case the journal
       ** file should be closed and deleted. If this connection writes to
-      ** the database file, it will do so using an in-memory journal. 
+      ** the database file, it will do so using an in-memory journal.
       */
-      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
+      int bDelete = !pPager->tempFile;
+      assert( sqlite3JournalIsInMemory(pPager->jfd)==0 );
       assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
            || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
            || pPager->journalMode==PAGER_JOURNALMODE_WAL 
@@ -45901,8 +48050,14 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
   sqlite3BitvecDestroy(pPager->pInJournal);
   pPager->pInJournal = 0;
   pPager->nRec = 0;
-  sqlite3PcacheCleanAll(pPager->pPCache);
-  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
+  if( rc==SQLITE_OK ){
+    if( pagerFlushOnCommit(pPager, bCommit) ){
+      sqlite3PcacheCleanAll(pPager->pPCache);
+    }else{
+      sqlite3PcacheClearWritable(pPager->pPCache);
+    }
+    sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
+  }
 
   if( pagerUseWal(pPager) ){
     /* Drop the WAL write-lock, if any. Also, if the connection was in 
@@ -46186,7 +48341,7 @@ static int pager_playback_one_page(
     pPg = sqlite3PagerLookup(pPager, pgno);
   }
   assert( pPg || !MEMDB );
-  assert( pPager->eState!=PAGER_OPEN || pPg==0 );
+  assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile );
   PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
            PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
            (isMainJrnl?"main-journal":"sub-journal")
@@ -46208,9 +48363,9 @@ static int pager_playback_one_page(
       pPager->dbFileSize = pgno;
     }
     if( pPager->pBackup ){
-      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
+      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
       sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
-      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
+      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
     }
   }else if( !isMainJrnl && pPg==0 ){
     /* If this is a rollback of a savepoint and data was not written to
@@ -46236,7 +48391,6 @@ static int pager_playback_one_page(
     assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
     pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
     if( rc!=SQLITE_OK ) return rc;
-    pPg->flags &= ~PGHDR_NEED_READ;
     sqlite3PcacheMakeDirty(pPg);
   }
   if( pPg ){
@@ -46250,29 +48404,10 @@ static int pager_playback_one_page(
     pData = pPg->pData;
     memcpy(pData, (u8*)aData, pPager->pageSize);
     pPager->xReiniter(pPg);
-    if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
-      /* If the contents of this page were just restored from the main 
-      ** journal file, then its content must be as they were when the 
-      ** transaction was first opened. In this case we can mark the page
-      ** as clean, since there will be no need to write it out to the
-      ** database.
-      **
-      ** There is one exception to this rule. If the page is being rolled
-      ** back as part of a savepoint (or statement) rollback from an 
-      ** unsynced portion of the main journal file, then it is not safe
-      ** to mark the page as clean. This is because marking the page as
-      ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
-      ** already in the journal file (recorded in Pager.pInJournal) and
-      ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
-      ** again within this transaction, it will be marked as dirty but
-      ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
-      ** be written out into the database file before its journal file
-      ** segment is synced. If a crash occurs during or following this,
-      ** database corruption may ensue.
-      */
-      assert( !pagerUseWal(pPager) );
-      sqlite3PcacheMakeClean(pPg);
-    }
+    /* It used to be that sqlite3PcacheMakeClean(pPg) was called here.  But
+    ** that call was dangerous and had no detectable benefit since the cache
+    ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so
+    ** has been removed. */
     pager_set_pagehash(pPg);
 
     /* If this was page 1, then restore the value of Pager.dbFileVers.
@@ -46282,7 +48417,7 @@ static int pager_playback_one_page(
     }
 
     /* Decode the page just read from disk */
-    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
+    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);
     sqlite3PcacheRelease(pPg);
   }
   return rc;
@@ -46348,7 +48483,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
   pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
   pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
   if( !pMaster ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }else{
     const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
     rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
@@ -46365,7 +48500,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
   nMasterPtr = pVfs->mxPathname+1;
   zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
   if( !zMasterJournal ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
     goto delmaster_out;
   }
   zMasterPtr = &zMasterJournal[nMasterJournal+1];
@@ -46613,7 +48748,7 @@ static int pager_playback(Pager *pPager, int isHot){
   ** TODO: Technically the following is an error because it assumes that
   ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
   ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
-  **  mxPathname is 512, which is the same as the minimum allowable value
+  ** mxPathname is 512, which is the same as the minimum allowable value
   ** for pageSize.
   */
   zMaster = pPager->pTmpSpace;
@@ -46835,7 +48970,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
       memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
     }
   }
-  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
+  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT);
 
   PAGER_INCR(sqlite3_pager_readdb_count);
   PAGER_INCR(pPager->nRead);
@@ -47063,6 +49198,8 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
   */
   assert( pPager->eState==PAGER_OPEN );
   assert( pPager->eLock>=SHARED_LOCK );
+  assert( isOpen(pPager->fd) );
+  assert( pPager->tempFile==0 );
   nPage = sqlite3WalDbsize(pPager->pWal);
 
   /* If the number of pages in the database is not available from the
@@ -47070,14 +49207,11 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
   ** the database file.  If the size of the database file is not an
   ** integer multiple of the page-size, round up the result.
   */
-  if( nPage==0 ){
+  if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){
     i64 n = 0;                    /* Size of db file in bytes */
-    assert( isOpen(pPager->fd) || pPager->tempFile );
-    if( isOpen(pPager->fd) ){
-      int rc = sqlite3OsFileSize(pPager->fd, &n);
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
+    int rc = sqlite3OsFileSize(pPager->fd, &n);
+    if( rc!=SQLITE_OK ){
+      return rc;
     }
     nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
   }
@@ -47195,7 +49329,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
   if( pSavepoint ){
     pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
     if( !pDone ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
   }
 
@@ -47342,7 +49476,7 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
 ** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
 ** of the database to damage due to OS crashes or power failures by
 ** changing the number of syncs()s when writing the journals.
-** There are three levels:
+** There are four levels:
 **
 **    OFF       sqlite3OsSync() is never called.  This is the default
 **              for temporary and transient files.
@@ -47362,6 +49496,10 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
 **              assurance that the journal will not be corrupted to the
 **              point of causing damage to the database during rollback.
 **
+**    EXTRA     This is like FULL except that is also syncs the directory
+**              that contains the rollback journal after the rollback
+**              journal is unlinked.
+**
 ** The above is for a rollback-journal mode.  For WAL mode, OFF continues
 ** to mean that no syncs ever occur.  NORMAL means that the WAL is synced
 ** prior to the start of checkpoint and that the database file is synced
@@ -47369,7 +49507,8 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
 ** was written back into the database.  But no sync operations occur for
 ** an ordinary commit in NORMAL mode with WAL.  FULL means that the WAL
 ** file is synced following each commit operation, in addition to the
-** syncs associated with NORMAL.
+** syncs associated with NORMAL.  There is no difference between FULL
+** and EXTRA for WAL mode.
 **
 ** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL.  The
 ** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
@@ -47558,7 +49697,7 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
     }
     if( rc==SQLITE_OK ){
       pNew = (char *)sqlite3PageMalloc(pageSize);
-      if( !pNew ) rc = SQLITE_NOMEM;
+      if( !pNew ) rc = SQLITE_NOMEM_BKPT;
     }
 
     if( rc==SQLITE_OK ){
@@ -47834,7 +49973,7 @@ static int pagerAcquireMapPage(
     *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
     if( p==0 ){
       sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     p->pExtra = (void *)&p[1];
     p->flags = PGHDR_MMAP;
@@ -48148,8 +50287,9 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
 
   /* This function is only called for rollback pagers in WRITER_DBMOD state. */
   assert( !pagerUseWal(pPager) );
-  assert( pPager->eState==PAGER_WRITER_DBMOD );
+  assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD );
   assert( pPager->eLock==EXCLUSIVE_LOCK );
+  assert( isOpen(pPager->fd) || pList->pDirty==0 );
 
   /* If the file is a temp-file has not yet been opened, open it now. It
   ** is not possible for rc to be other than SQLITE_OK if this branch
@@ -48192,7 +50332,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
       if( pList->pgno==1 ) pager_write_changecounter(pList);
 
       /* Encode the database */
-      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
+      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData);
 
       /* Write out the page data. */
       rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
@@ -48237,11 +50377,14 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
 static int openSubJournal(Pager *pPager){
   int rc = SQLITE_OK;
   if( !isOpen(pPager->sjfd) ){
+    const int flags =  SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE 
+      | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE 
+      | SQLITE_OPEN_DELETEONCLOSE;
+    int nStmtSpill = sqlite3Config.nStmtSpill;
     if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
-      sqlite3MemJournalOpen(pPager->sjfd);
-    }else{
-      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
+      nStmtSpill = -1;
     }
+    rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill);
   }
   return rc;
 }
@@ -48279,7 +50422,7 @@ static int subjournalPage(PgHdr *pPg){
       i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
       char *pData2;
   
-      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
       PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
       rc = write32bits(pPager->sjfd, offset, pPg->pgno);
       if( rc==SQLITE_OK ){
@@ -48462,18 +50605,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
   int nUri = 0;            /* Number of bytes of URI args at *zUri */
 
   /* Figure out how much space is required for each journal file-handle
-  ** (there are two of them, the main journal and the sub-journal). This
-  ** is the maximum space required for an in-memory journal file handle 
-  ** and a regular journal file-handle. Note that a "regular journal-handle"
-  ** may be a wrapper capable of caching the first portion of the journal
-  ** file in memory to implement the atomic-write optimization (see 
-  ** source file journal.c).
-  */
-  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
-    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
-  }else{
-    journalFileSize = ROUND8(sqlite3MemJournalSize());
-  }
+  ** (there are two of them, the main journal and the sub-journal).  */
+  journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
 
   /* Set the output variable to NULL in case an error occurs. */
   *ppPager = 0;
@@ -48483,7 +50616,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
     memDb = 1;
     if( zFilename && zFilename[0] ){
       zPathname = sqlite3DbStrDup(0, zFilename);
-      if( zPathname==0  ) return SQLITE_NOMEM;
+      if( zPathname==0  ) return SQLITE_NOMEM_BKPT;
       nPathname = sqlite3Strlen30(zPathname);
       zFilename = 0;
     }
@@ -48499,7 +50632,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
     nPathname = pVfs->mxPathname+1;
     zPathname = sqlite3DbMallocRaw(0, nPathname*2);
     if( zPathname==0 ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
     rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
@@ -48552,7 +50685,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
   assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
   if( !pPtr ){
     sqlite3DbFree(0, zPathname);
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   pPager =              (Pager*)(pPtr);
   pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
@@ -48707,11 +50840,7 @@ act_like_temp_file:
     assert( pPager->ckptSyncFlags==0 );
   }else{
     pPager->fullSync = 1;
-#if SQLITE_EXTRA_DURABLE
-    pPager->extraSync = 1;
-#else
     pPager->extraSync = 0;
-#endif
     pPager->syncFlags = SQLITE_SYNC_NORMAL;
     pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
     pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
@@ -48828,6 +50957,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
     if( rc==SQLITE_OK && !locked ){
       Pgno nPage;                 /* Number of pages in database file */
 
+      assert( pPager->tempFile==0 );
       rc = pagerPagecount(pPager, &nPage);
       if( rc==SQLITE_OK ){
         /* If the database is zero pages in size, that means that either (1) the
@@ -48920,17 +51050,17 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
   /* This routine is only called from b-tree and only when there are no
   ** outstanding pages. This implies that the pager state should either
   ** be OPEN or READER. READER is only possible if the pager is or was in 
-  ** exclusive access mode.
-  */
+  ** exclusive access mode.  */
   assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
   assert( assert_pager_state(pPager) );
   assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
-  if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
+  assert( pPager->errCode==SQLITE_OK );
 
   if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
     int bHotJournal = 1;          /* True if there exists a hot journal-file */
 
     assert( !MEMDB );
+    assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK );
 
     rc = pager_wait_on_lock(pPager, SHARED_LOCK);
     if( rc!=SQLITE_OK ){
@@ -49016,7 +51146,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
         assert( rc==SQLITE_OK );
         rc = pagerSyncHotJournal(pPager);
         if( rc==SQLITE_OK ){
-          rc = pager_playback(pPager, 1);
+          rc = pager_playback(pPager, !pPager->tempFile);
           pPager->eState = PAGER_OPEN;
         }
       }else if( !pPager->exclusiveMode ){
@@ -49112,7 +51242,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
     rc = pagerBeginReadTransaction(pPager);
   }
 
-  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
+  if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
     rc = pagerPagecount(pPager, &pPager->dbSize);
   }
 
@@ -49245,7 +51375,7 @@ SQLITE_PRIVATE int sqlite3PagerGet(
       );
 
       if( rc==SQLITE_OK && pData ){
-        if( pPager->eState>PAGER_READER ){
+        if( pPager->eState>PAGER_READER || pPager->tempFile ){
           pPg = sqlite3PagerLookup(pPager, pgno);
         }
         if( pPg==0 ){
@@ -49272,7 +51402,7 @@ SQLITE_PRIVATE int sqlite3PagerGet(
         if( rc!=SQLITE_OK ) goto pager_acquire_err;
         if( pBase==0 ){
           pPg = *ppPage = 0;
-          rc = SQLITE_NOMEM;
+          rc = SQLITE_NOMEM_BKPT;
           goto pager_acquire_err;
         }
       }
@@ -49312,7 +51442,8 @@ SQLITE_PRIVATE int sqlite3PagerGet(
       goto pager_acquire_err;
     }
 
-    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
+    assert( !isOpen(pPager->fd) || !MEMDB );
+    if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
       if( pgno>pPager->mxPgno ){
         rc = SQLITE_FULL;
         goto pager_acquire_err;
@@ -49446,7 +51577,7 @@ static int pager_open_journal(Pager *pPager){
   if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
     pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
     if( pPager->pInJournal==0 ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
   
     /* Open the journal file if it is not already open. */
@@ -49454,24 +51585,24 @@ static int pager_open_journal(Pager *pPager){
       if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
         sqlite3MemJournalOpen(pPager->jfd);
       }else{
-        const int flags =                   /* VFS flags to open journal file */
-          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
-          (pPager->tempFile ? 
-            (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
-            (SQLITE_OPEN_MAIN_JOURNAL)
-          );
+        int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
+        int nSpill;
 
+        if( pPager->tempFile ){
+          flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
+          nSpill = sqlite3Config.nStmtSpill;
+        }else{
+          flags |= SQLITE_OPEN_MAIN_JOURNAL;
+          nSpill = jrnlBufferSize(pPager);
+        }
+          
         /* Verify that the database still has the same name as it did when
         ** it was originally opened. */
         rc = databaseIsUnmoved(pPager);
         if( rc==SQLITE_OK ){
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-          rc = sqlite3JournalOpen(
-              pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
+          rc = sqlite3JournalOpen (
+              pVfs, pPager->zJournal, pPager->jfd, flags, nSpill
           );
-#else
-          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
-#endif
         }
       }
       assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
@@ -49601,7 +51732,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
   assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
 
   assert( pPager->journalHdr<=pPager->journalOff );
-  CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+  CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
   cksum = pager_cksum(pPager, (u8*)pData2);
 
   /* Even if an IO or diskfull error occurs while journalling the
@@ -49842,6 +51973,7 @@ SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
     if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
     return SQLITE_OK;
   }else if( pPager->sectorSize > (u32)pPager->pageSize ){
+    assert( pPager->tempFile==0 );
     return pagerWriteLargeSector(pPg);
   }else{
     return pager_write(pPg);
@@ -49872,14 +52004,21 @@ SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
 **
 ** Tests show that this optimization can quadruple the speed of large 
 ** DELETE operations.
+**
+** This optimization cannot be used with a temp-file, as the page may
+** have been dirty at the start of the transaction. In that case, if
+** memory pressure forces page pPg out of the cache, the data does need 
+** to be written out to disk so that it may be read back in if the 
+** current transaction is rolled back.
 */
 SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
   Pager *pPager = pPg->pPager;
-  if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
+  if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
     PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
     IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
     pPg->flags |= PGHDR_DONT_WRITE;
     pPg->flags &= ~PGHDR_WRITEABLE;
+    testcase( pPg->flags & PGHDR_NEED_SYNC );
     pager_set_pagehash(pPg);
   }
 }
@@ -49958,7 +52097,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
       if( DIRECT_MODE ){
         const void *zBuf;
         assert( pPager->dbFileSize>0 );
-        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
+        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf);
         if( rc==SQLITE_OK ){
           rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
           pPager->aStat[PAGER_STAT_WRITE]++;
@@ -50074,17 +52213,21 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
   /* If a prior error occurred, report that error again. */
   if( NEVER(pPager->errCode) ) return pPager->errCode;
 
+  /* Provide the ability to easily simulate an I/O error during testing */
+  if( sqlite3FaultSim(400) ) return SQLITE_IOERR;
+
   PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
       pPager->zFilename, zMaster, pPager->dbSize));
 
   /* If no database changes have been made, return early. */
   if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
 
-  if( MEMDB ){
+  assert( MEMDB==0 || pPager->tempFile );
+  assert( isOpen(pPager->fd) || pPager->tempFile );
+  if( 0==pagerFlushOnCommit(pPager, 1) ){
     /* If this is an in-memory db, or no pages have been written to, or this
     ** function has already been called, it is mostly a no-op.  However, any
-    ** backup in progress needs to be restarted.
-    */
+    ** backup in progress needs to be restarted.  */
     sqlite3BackupRestart(pPager->pBackup);
   }else{
     if( pagerUseWal(pPager) ){
@@ -50423,10 +52566,10 @@ SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, i
 }
 
 /*
-** Return true if this is an in-memory pager.
+** Return true if this is an in-memory or temp-file backed pager.
 */
 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
-  return MEMDB;
+  return pPager->tempFile;
 }
 
 /*
@@ -50457,7 +52600,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
       pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
   );
   if( !aNew ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
   pPager->aSavepoint = aNew;
@@ -50473,7 +52616,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
     aNew[ii].iSubRec = pPager->nSubRec;
     aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
     if( !aNew[ii].pInSavepoint ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     if( pagerUseWal(pPager) ){
       sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
@@ -50551,7 +52694,7 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
     if( op==SAVEPOINT_RELEASE ){
       if( nNew==0 && isOpen(pPager->sjfd) ){
         /* Only truncate if it is an in-memory sub-journal. */
-        if( sqlite3IsMemJournal(pPager->sjfd) ){
+        if( sqlite3JournalIsInMemory(pPager->sjfd) ){
           rc = sqlite3OsTruncate(pPager->sjfd, 0);
           assert( rc==SQLITE_OK );
         }
@@ -50622,14 +52765,6 @@ SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
   return pPager->zJournal;
 }
 
-/*
-** Return true if fsync() calls are disabled for this pager.  Return FALSE
-** if fsync()s are executed normally.
-*/
-SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
-  return pPager->noSync;
-}
-
 #ifdef SQLITE_HAS_CODEC
 /*
 ** Set or retrieve the codec for this pager
@@ -50714,7 +52849,8 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
   /* In order to be able to rollback, an in-memory database must journal
   ** the page we are moving from.
   */
-  if( MEMDB ){
+  assert( pPager->tempFile || !MEMDB );
+  if( pPager->tempFile ){
     rc = sqlite3PagerWrite(pPg);
     if( rc ) return rc;
   }
@@ -50771,7 +52907,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
   assert( !pPgOld || pPgOld->nRef==1 );
   if( pPgOld ){
     pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
-    if( MEMDB ){
+    if( pPager->tempFile ){
       /* Do not discard pages from an in-memory database since we might
       ** need to rollback later.  Just move the page out of the way. */
       sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
@@ -50788,8 +52924,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
   ** to exist, in case the transaction needs to roll back.  Use pPgOld
   ** as the original page since it has already been allocated.
   */
-  if( MEMDB ){
-    assert( pPgOld );
+  if( pPager->tempFile && pPgOld ){
     sqlite3PcacheMove(pPgOld, origPgno);
     sqlite3PagerUnrefNotNull(pPgOld);
   }
@@ -51041,7 +53176,8 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
 ** Unless this is an in-memory or temporary database, clear the pager cache.
 */
 SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
-  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
+  assert( MEMDB==0 || pPager->tempFile );
+  if( pPager->tempFile==0 ) pager_reset(pPager);
 }
 #endif
 
@@ -51076,6 +53212,7 @@ SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
 */
 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
   const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
+  if( pPager->noLock ) return 0;
   return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
 }
 
@@ -51219,6 +53356,7 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
                            pPager->pageSize, (u8*)pPager->pTmpSpace);
       pPager->pWal = 0;
       pagerFixMaplimit(pPager);
+      if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
     }
   }
   return rc;
@@ -51821,7 +53959,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
     apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte);
     if( !apNew ){
       *ppPage = 0;
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     memset((void*)&apNew[pWal->nWiData], 0,
            sizeof(u32*)*(iPage+1-pWal->nWiData));
@@ -51833,7 +53971,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
   if( pWal->apWiData[iPage]==0 ){
     if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
       pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
-      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
+      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
     }else{
       rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
           pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
@@ -52448,7 +54586,7 @@ static int walIndexRecover(Wal *pWal){
     szFrame = szPage + WAL_FRAME_HDRSIZE;
     aFrame = (u8 *)sqlite3Malloc(szFrame);
     if( !aFrame ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
       goto recovery_error;
     }
     aData = &aFrame[WAL_FRAME_HDRSIZE];
@@ -52586,7 +54724,7 @@ SQLITE_PRIVATE int sqlite3WalOpen(
   *ppWal = 0;
   pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
   if( !pRet ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 
   pRet->pVfs = pVfs;
@@ -52850,7 +54988,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
         + iLast*sizeof(ht_slot);
   p = (WalIterator *)sqlite3Malloc(nByte);
   if( !p ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   memset(p, 0, nByte);
   p->nSegment = nSegment;
@@ -52862,7 +55000,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
       sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
   );
   if( !aTmp ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }
 
   for(i=0; rc==SQLITE_OK && i<nSegment; i++){
@@ -54155,7 +56293,7 @@ static int walWriteOneFrame(
   void *pData;                    /* Data actually written */
   u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
 #if defined(SQLITE_HAS_CODEC)
-  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
+  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
 #else
   pData = pPage->pData;
 #endif
@@ -54184,7 +56322,7 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){
   i64 iCksumOff;
 
   aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
-  if( aBuf==0 ) return SQLITE_NOMEM;
+  if( aBuf==0 ) return SQLITE_NOMEM_BKPT;
 
   /* Find the checksum values to use as input for the recalculating the
   ** first checksum. If the first frame is frame 1 (implying that the current
@@ -54660,7 +56798,7 @@ SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapsho
 
   pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
   if( pRet==0 ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }else{
     memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
     *ppSnapshot = (sqlite3_snapshot*)pRet;
@@ -54674,6 +56812,23 @@ SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapsho
 SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
   pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
 }
+
+/* 
+** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
+** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
+  WalIndexHdr *pHdr1 = (WalIndexHdr*)p1;
+  WalIndexHdr *pHdr2 = (WalIndexHdr*)p2;
+
+  /* aSalt[0] is a copy of the value stored in the wal file header. It
+  ** is incremented each time the wal file is restarted.  */
+  if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1;
+  if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1;
+  if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1;
+  if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
+  return 0;
+}
 #endif /* SQLITE_ENABLE_SNAPSHOT */
 
 #ifdef SQLITE_ENABLE_ZIPVFS
@@ -56063,7 +58218,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
   if( !pLock ){
     pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
     if( !pLock ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     pLock->iTable = iTable;
     pLock->pBtree = p;
@@ -56266,7 +58421,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
     assert( pgno<=pBt->nPage );
     pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
     if( !pBt->pHasContent ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }
   }
   if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
@@ -56345,7 +58500,7 @@ static int saveCursorKey(BtCursor *pCur){
         sqlite3_free(pKey);
       }
     }else{
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }
   }
   assert( !pCur->curIntKey || !pCur->pKey );
@@ -56477,7 +58632,7 @@ static int btreeMoveto(
     pIdxKey = sqlite3VdbeAllocUnpackedRecord(
         pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
     );
-    if( pIdxKey==0 ) return SQLITE_NOMEM;
+    if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
     sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
     if( pIdxKey->nField==0 ){
       sqlite3DbFree(pCur->pKeyInfo->db, pFree);
@@ -57389,11 +59544,11 @@ static int decodeFlags(MemPage *pPage, int flagByte){
   pPage->xCellSize = cellSizePtr;
   pBt = pPage->pBt;
   if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
-    /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior
-    ** table b-tree page. */
+    /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
+    ** interior table b-tree page. */
     assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
-    /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf
-    ** table b-tree page. */
+    /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a
+    ** leaf table b-tree page. */
     assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
     pPage->intKey = 1;
     if( pPage->leaf ){
@@ -57407,11 +59562,11 @@ static int decodeFlags(MemPage *pPage, int flagByte){
     pPage->maxLocal = pBt->maxLeaf;
     pPage->minLocal = pBt->minLeaf;
   }else if( flagByte==PTF_ZERODATA ){
-    /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior
-    ** index b-tree page. */
+    /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an
+    ** interior index b-tree page. */
     assert( (PTF_ZERODATA)==2 );
-    /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf
-    ** index b-tree page. */
+    /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
+    ** leaf index b-tree page. */
     assert( (PTF_ZERODATA|PTF_LEAF)==10 );
     pPage->intKey = 0;
     pPage->intKeyLeaf = 0;
@@ -57889,7 +60044,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
   }
   p = sqlite3MallocZero(sizeof(Btree));
   if( !p ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   p->inTrans = TRANS_NONE;
   p->db = db;
@@ -57913,7 +60068,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
       p->sharable = 1;
       if( !zFullPathname ){
         sqlite3_free(p);
-        return SQLITE_NOMEM;
+        return SQLITE_NOMEM_BKPT;
       }
       if( isMemdb ){
         memcpy(zFullPathname, zFilename, nFilename);
@@ -57981,7 +60136,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
   
     pBt = sqlite3MallocZero( sizeof(*pBt) );
     if( pBt==0 ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
       goto btree_open_out;
     }
     rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
@@ -58050,7 +60205,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
       if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
         pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
         if( pBt->mutex==0 ){
-          rc = SQLITE_NOMEM;
+          rc = SQLITE_NOMEM_BKPT;
           goto btree_open_out;
         }
       }
@@ -58073,12 +60228,12 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
     for(i=0; i<db->nDb; i++){
       if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
         while( pSib->pPrev ){ pSib = pSib->pPrev; }
-        if( p->pBt<pSib->pBt ){
+        if( (uptr)p->pBt<(uptr)pSib->pBt ){
           p->pNext = pSib;
           p->pPrev = 0;
           pSib->pPrev = p;
         }else{
-          while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
+          while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){
             pSib = pSib->pNext;
           }
           p->pNext = pSib->pNext;
@@ -58333,21 +60488,6 @@ SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(
 #endif
 
 /*
-** Return TRUE if the given btree is set to safety level 1.  In other
-** words, return TRUE if no sync() occurs on the disk files.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree *p){
-  BtShared *pBt = p->pBt;
-  int rc;
-  assert( sqlite3_mutex_held(p->db->mutex) );  
-  sqlite3BtreeEnter(p);
-  assert( pBt && pBt->pPager );
-  rc = sqlite3PagerNosync(pBt->pPager);
-  sqlite3BtreeLeave(p);
-  return rc;
-}
-
-/*
 ** Change the default pages size and the number of reserved bytes per page.
 ** Or, if the page size has already been fixed, return SQLITE_READONLY 
 ** without changing anything.
@@ -58592,9 +60732,25 @@ static int lockBtree(BtShared *pBt){
       rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
       if( rc!=SQLITE_OK ){
         goto page1_init_failed;
-      }else if( isOpen==0 ){
-        releasePage(pPage1);
-        return SQLITE_OK;
+      }else{
+#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
+        sqlite3 *db;
+        Db *pDb;
+        if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
+          while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
+          if( pDb->bSyncSet==0
+           && pDb->safety_level==SQLITE_DEFAULT_SYNCHRONOUS+1
+          ){
+            pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1;
+            sqlite3PagerSetFlags(pBt->pPager,
+               pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
+          }
+        }
+#endif
+        if( isOpen==0 ){
+          releasePage(pPage1);
+          return SQLITE_OK;
+        }
       }
       rc = SQLITE_NOTADB;
     }
@@ -59827,7 +61983,7 @@ static int btreeCursor(
 
   if( wrFlag ){
     allocateTempSpace(pBt);
-    if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
+    if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
   }
   if( iTable==1 && btreePagecount(pBt)==0 ){
     assert( wrFlag==0 );
@@ -60184,8 +62340,13 @@ static int accessPayload(
 #endif
   assert( offset+amt <= pCur->info.nPayload );
 
-  if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){
-    /* Trying to read or write past the end of the data is an error */
+  assert( aPayload > pPage->aData );
+  if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){
+    /* Trying to read or write past the end of the data is an error.  The
+    ** conditional above is really:
+    **    &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
+    ** but is recast into its current form to avoid integer overflow problems
+    */
     return SQLITE_CORRUPT_BKPT;
   }
 
@@ -60225,7 +62386,7 @@ static int accessPayload(
             pCur->aOverflow, nOvfl*2*sizeof(Pgno)
         );
         if( aNew==0 ){
-          rc = SQLITE_NOMEM;
+          rc = SQLITE_NOMEM_BKPT;
         }else{
           pCur->nOvflAlloc = nOvfl*2;
           pCur->aOverflow = aNew;
@@ -60930,7 +63091,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
           }
           pCellKey = sqlite3Malloc( nCell+18 );
           if( pCellKey==0 ){
-            rc = SQLITE_NOMEM;
+            rc = SQLITE_NOMEM_BKPT;
             goto moveto_finish;
           }
           pCur->aiIdx[pCur->iPage] = (u16)idx;
@@ -62252,8 +64413,8 @@ static int pageInsertArray(
     u8 *pSlot;
     sz = cachedCellSize(pCArray, i);
     if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
+      if( (pData - pBegin)<sz ) return 1;
       pData -= sz;
-      if( pData<pBegin ) return 1;
       pSlot = pData;
     }
     /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
@@ -62415,7 +64576,7 @@ static int editPage(
   for(i=0; i<nNew && !CORRUPT_DB; i++){
     u8 *pCell = pCArray->apCell[i+iNew];
     int iOff = get2byteAligned(&pPg->aCellIdx[i*2]);
-    if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
+    if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){
       pCell = &pTmp[pCell - aData];
     }
     assert( 0==memcmp(pCell, &aData[iOff],
@@ -62749,7 +64910,7 @@ static int balance_nonroot(
   assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
 
   if( !aOvflSpace ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 
   /* Find the sibling pages to balance. Also locate the cells in pParent 
@@ -62849,7 +65010,7 @@ static int balance_nonroot(
   assert( szScratch<=6*(int)pBt->pageSize );
   b.apCell = sqlite3ScratchMalloc( szScratch ); 
   if( b.apCell==0 ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
     goto balance_cleanup;
   }
   b.szCell = (u16*)&b.apCell[nMaxCells];
@@ -63284,9 +65445,9 @@ static int balance_nonroot(
       ** any cell). But it is important to pass the correct size to 
       ** insertCell(), so reparse the cell now.
       **
-      ** Note that this can never happen in an SQLite data file, as all
-      ** cells are at least 4 bytes. It only happens in b-trees used
-      ** to evaluate "IN (SELECT ...)" and similar clauses.
+      ** This can only happen for b-trees used to evaluate "IN (SELECT ...)"
+      ** and WITHOUT ROWID tables with exactly one column which is the
+      ** primary key.
       */
       if( b.szCell[j]==4 ){
         assert(leafCorrection==4);
@@ -63847,6 +66008,28 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
   pPage = pCur->apPage[iCellDepth];
   pCell = findCell(pPage, iCellIdx);
 
+  /* If the bPreserve flag is set to true, then the cursor position must
+  ** be preserved following this delete operation. If the current delete
+  ** will cause a b-tree rebalance, then this is done by saving the cursor
+  ** key and leaving the cursor in CURSOR_REQUIRESEEK state before 
+  ** returning. 
+  **
+  ** Or, if the current delete will not cause a rebalance, then the cursor
+  ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
+  ** before or after the deleted entry. In this case set bSkipnext to true.  */
+  if( bPreserve ){
+    if( !pPage->leaf 
+     || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+    ){
+      /* A b-tree rebalance will be required after deleting this entry.
+      ** Save the cursor key.  */
+      rc = saveCursorKey(pCur);
+      if( rc ) return rc;
+    }else{
+      bSkipnext = 1;
+    }
+  }
+
   /* If the page containing the entry to delete is not a leaf page, move
   ** the cursor to the largest entry in the tree that is smaller than
   ** the entry being deleted. This cell will replace the cell being deleted
@@ -63873,28 +66056,6 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
     invalidateIncrblobCursors(p, pCur->info.nKey, 0);
   }
 
-  /* If the bPreserve flag is set to true, then the cursor position must
-  ** be preserved following this delete operation. If the current delete
-  ** will cause a b-tree rebalance, then this is done by saving the cursor
-  ** key and leaving the cursor in CURSOR_REQUIRESEEK state before 
-  ** returning. 
-  **
-  ** Or, if the current delete will not cause a rebalance, then the cursor
-  ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
-  ** before or after the deleted entry. In this case set bSkipnext to true.  */
-  if( bPreserve ){
-    if( !pPage->leaf 
-     || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
-    ){
-      /* A b-tree rebalance will be required after deleting this entry.
-      ** Save the cursor key.  */
-      rc = saveCursorKey(pCur);
-      if( rc ) return rc;
-    }else{
-      bSkipnext = 1;
-    }
-  }
-
   /* Make the page containing the entry to be deleted writable. Then free any
   ** overflow pages associated with the entry and finally remove the cell
   ** itself from within the page.  */
@@ -65505,7 +67666,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
     pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
     if( pParse==0 ){
       sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }else{
       pParse->db = pDb;
       if( sqlite3OpenTempDatabase(pParse) ){
@@ -65599,7 +67760,7 @@ SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
     ** sqlite3_backup_finish(). */
     p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
     if( !p ){
-      sqlite3Error(pDestDb, SQLITE_NOMEM);
+      sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT);
     }
   }
 
@@ -65998,7 +68159,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
     }
   
     if( rc==SQLITE_IOERR_NOMEM ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }
     p->rc = rc;
   }
@@ -66355,7 +68516,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
       sqlite3VdbeMemSetNull(pMem);
       pMem->z = 0;
       pMem->szMalloc = 0;
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }else{
       pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
     }
@@ -66413,7 +68574,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
   f = pMem->flags;
   if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
     if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     pMem->z[pMem->n] = 0;
     pMem->z[pMem->n+1] = 0;
@@ -66445,7 +68606,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
       nByte = 1;
     }
     if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
 
     memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
@@ -66462,7 +68623,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
 */
 static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
   if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   pMem->z[pMem->n] = 0;
   pMem->z[pMem->n+1] = 0;
@@ -66511,7 +68672,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
 
 
   if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 
   /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
@@ -66978,7 +69139,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){
 SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
   int i;
   Mem *pX;
-  for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
+  for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
     if( pX->pScopyFrom==pMem ){
       pX->flags |= MEM_Undefined;
       pX->pScopyFrom = 0;
@@ -67019,10 +69180,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int sr
 SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
   int rc = SQLITE_OK;
 
-  /* The pFrom==0 case in the following assert() is when an sqlite3_value
-  ** from sqlite3_value_dup() is used as the argument
-  ** to sqlite3_result_value(). */
-  assert( pTo->db==pFrom->db || pFrom->db==0 );
   assert( (pFrom->flags & MEM_RowSet)==0 );
   if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
   memcpy(pTo, pFrom, MEMCELLSIZE);
@@ -67122,7 +69279,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
     testcase( nAlloc==31 );
     testcase( nAlloc==32 );
     if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     memcpy(pMem->z, z, nAlloc);
   }else if( xDel==SQLITE_DYNAMIC ){
@@ -67142,7 +69299,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
 
 #ifndef SQLITE_OMIT_UTF16
   if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 #endif
 
@@ -67403,7 +69560,6 @@ static int valueFromFunction(
   FuncDef *pFunc = 0;             /* Function definition */
   sqlite3_value *pVal = 0;        /* New value */
   int rc = SQLITE_OK;             /* Return code */
-  int nName;                      /* Size of function name in bytes */
   ExprList *pList = 0;            /* Function arguments */
   int i;                          /* Iterator variable */
 
@@ -67411,8 +69567,7 @@ static int valueFromFunction(
   assert( (p->flags & EP_TokenOnly)==0 );
   pList = p->x.pList;
   if( pList ) nVal = pList->nExpr;
-  nName = sqlite3Strlen30(p->u.zToken);
-  pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
+  pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
   assert( pFunc );
   if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 
    || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -67423,7 +69578,7 @@ static int valueFromFunction(
   if( pList ){
     apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
     if( apVal==0 ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
       goto value_from_function_out;
     }
     for(i=0; i<nVal; i++){
@@ -67434,7 +69589,7 @@ static int valueFromFunction(
 
   pVal = valueNew(db, pCtx);
   if( pVal==0 ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
     goto value_from_function_out;
   }
 
@@ -67504,7 +69659,7 @@ static int valueFromExpr(
     *ppVal = 0;
     return SQLITE_OK;
   }
-  while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
+  while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
   if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
 
   /* Compressed expressions only appear when parsing the DEFAULT clause
@@ -67607,7 +69762,7 @@ no_mem:
 #else
   assert( pCtx==0 ); sqlite3ValueFree(pVal);
 #endif
-  return SQLITE_NOMEM;
+  return SQLITE_NOMEM_BKPT;
 }
 
 /*
@@ -67674,15 +69829,10 @@ static void recordFunc(
 ** Register built-in functions used to help read ANALYZE data.
 */
 SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){
-  static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = {
+  static FuncDef aAnalyzeTableFuncs[] = {
     FUNCTION(sqlite_record,   1, 0, 0, recordFunc),
   };
-  int i;
-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
-  for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
-  }
+  sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs));
 }
 
 /*
@@ -67861,7 +70011,7 @@ SQLITE_PRIVATE int sqlite3Stat4Column(
   if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
   if( pMem==0 ){
     pMem = *ppVal = sqlite3ValueNew(db);
-    if( pMem==0 ) return SQLITE_NOMEM;
+    if( pMem==0 ) return SQLITE_NOMEM_BKPT;
   }
   sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
   pMem->enc = ENC(db);
@@ -68017,6 +70167,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
 SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
   Vdbe tmp, *pTmp;
   char *zTmp;
+  assert( pA->db==pB->db );
   tmp = *pA;
   *pA = *pB;
   *pB = tmp;
@@ -68068,7 +70219,7 @@ static int growOpArray(Vdbe *v, int nOp){
     p->nOpAlloc = p->szOpAlloc/sizeof(Op);
     v->aOp = pNew;
   }
-  return (pNew ? SQLITE_OK : SQLITE_NOMEM);
+  return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
 }
 
 #ifdef SQLITE_DEBUG
@@ -68330,6 +70481,13 @@ SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
   p->runOnlyOnce = 1;
 }
 
+/*
+** Mark the VDBE as one that can only be run multiple times.
+*/
+SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
+  p->runOnlyOnce = 0;
+}
+
 #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
 
 /*
@@ -68476,73 +70634,84 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
 ** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
 **
 ** (5) Reclaim the memory allocated for storing labels.
+**
+** This routine will only function correctly if the mkopcodeh.tcl generator
+** script numbers the opcodes correctly.  Changes to this routine must be
+** coordinated with changes to mkopcodeh.tcl.
 */
 static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
-  int i;
   int nMaxArgs = *pMaxFuncArgs;
   Op *pOp;
   Parse *pParse = p->pParse;
   int *aLabel = pParse->aLabel;
   p->readOnly = 1;
   p->bIsReader = 0;
-  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
-    u8 opcode = pOp->opcode;
-
-    /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
-    ** cases from this switch! */
-    switch( opcode ){
-      case OP_Transaction: {
-        if( pOp->p2!=0 ) p->readOnly = 0;
-        /* fall thru */
-      }
-      case OP_AutoCommit:
-      case OP_Savepoint: {
-        p->bIsReader = 1;
-        break;
-      }
+  pOp = &p->aOp[p->nOp-1];
+  while(1){
+
+    /* Only JUMP opcodes and the short list of special opcodes in the switch
+    ** below need to be considered.  The mkopcodeh.tcl generator script groups
+    ** all these opcodes together near the front of the opcode list.  Skip
+    ** any opcode that does not need processing by virtual of the fact that
+    ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
+    */
+    if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
+      /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
+      ** cases from this switch! */
+      switch( pOp->opcode ){
+        case OP_Transaction: {
+          if( pOp->p2!=0 ) p->readOnly = 0;
+          /* fall thru */
+        }
+        case OP_AutoCommit:
+        case OP_Savepoint: {
+          p->bIsReader = 1;
+          break;
+        }
 #ifndef SQLITE_OMIT_WAL
-      case OP_Checkpoint:
+        case OP_Checkpoint:
 #endif
-      case OP_Vacuum:
-      case OP_JournalMode: {
-        p->readOnly = 0;
-        p->bIsReader = 1;
-        break;
-      }
+        case OP_Vacuum:
+        case OP_JournalMode: {
+          p->readOnly = 0;
+          p->bIsReader = 1;
+          break;
+        }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-      case OP_VUpdate: {
-        if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
-        break;
-      }
-      case OP_VFilter: {
-        int n;
-        assert( p->nOp - i >= 3 );
-        assert( pOp[-1].opcode==OP_Integer );
-        n = pOp[-1].p1;
-        if( n>nMaxArgs ) nMaxArgs = n;
-        break;
-      }
+        case OP_VUpdate: {
+          if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+          break;
+        }
+        case OP_VFilter: {
+          int n;
+          assert( (pOp - p->aOp) >= 3 );
+          assert( pOp[-1].opcode==OP_Integer );
+          n = pOp[-1].p1;
+          if( n>nMaxArgs ) nMaxArgs = n;
+          break;
+        }
 #endif
-      case OP_Next:
-      case OP_NextIfOpen:
-      case OP_SorterNext: {
-        pOp->p4.xAdvance = sqlite3BtreeNext;
-        pOp->p4type = P4_ADVANCE;
-        break;
+        case OP_Next:
+        case OP_NextIfOpen:
+        case OP_SorterNext: {
+          pOp->p4.xAdvance = sqlite3BtreeNext;
+          pOp->p4type = P4_ADVANCE;
+          break;
+        }
+        case OP_Prev:
+        case OP_PrevIfOpen: {
+          pOp->p4.xAdvance = sqlite3BtreePrevious;
+          pOp->p4type = P4_ADVANCE;
+          break;
+        }
       }
-      case OP_Prev:
-      case OP_PrevIfOpen: {
-        pOp->p4.xAdvance = sqlite3BtreePrevious;
-        pOp->p4type = P4_ADVANCE;
-        break;
+      if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
+        assert( ADDR(pOp->p2)<pParse->nLabel );
+        pOp->p2 = aLabel[ADDR(pOp->p2)];
       }
     }
-
-    pOp->opflags = sqlite3OpcodeProperty[opcode];
-    if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
-      assert( ADDR(pOp->p2)<pParse->nLabel );
-      pOp->p2 = aLabel[ADDR(pOp->p2)];
-    }
+    if( pOp==p->aOp ) break;
+    pOp--;
   }
   sqlite3DbFree(p->db, pParse->aLabel);
   pParse->aLabel = 0;
@@ -68722,52 +70891,50 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
 ** Delete a P4 value if necessary.
 */
 static void freeP4(sqlite3 *db, int p4type, void *p4){
-  if( p4 ){
-    assert( db );
-    switch( p4type ){
-      case P4_FUNCCTX: {
-        freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
-        /* Fall through into the next case */
-      }
-      case P4_REAL:
-      case P4_INT64:
-      case P4_DYNAMIC:
-      case P4_INTARRAY: {
-        sqlite3DbFree(db, p4);
-        break;
-      }
-      case P4_KEYINFO: {
-        if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
-        break;
-      }
+  assert( db );
+  switch( p4type ){
+    case P4_FUNCCTX: {
+      freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
+      /* Fall through into the next case */
+    }
+    case P4_REAL:
+    case P4_INT64:
+    case P4_DYNAMIC:
+    case P4_INTARRAY: {
+      sqlite3DbFree(db, p4);
+      break;
+    }
+    case P4_KEYINFO: {
+      if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
+      break;
+    }
 #ifdef SQLITE_ENABLE_CURSOR_HINTS
-      case P4_EXPR: {
-        sqlite3ExprDelete(db, (Expr*)p4);
-        break;
-      }
+    case P4_EXPR: {
+      sqlite3ExprDelete(db, (Expr*)p4);
+      break;
+    }
 #endif
-      case P4_MPRINTF: {
-        if( db->pnBytesFreed==0 ) sqlite3_free(p4);
-        break;
-      }
-      case P4_FUNCDEF: {
-        freeEphemeralFunction(db, (FuncDef*)p4);
-        break;
-      }
-      case P4_MEM: {
-        if( db->pnBytesFreed==0 ){
-          sqlite3ValueFree((sqlite3_value*)p4);
-        }else{
-          Mem *p = (Mem*)p4;
-          if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
-          sqlite3DbFree(db, p);
-        }
-        break;
-      }
-      case P4_VTAB : {
-        if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
-        break;
+    case P4_MPRINTF: {
+      if( db->pnBytesFreed==0 ) sqlite3_free(p4);
+      break;
+    }
+    case P4_FUNCDEF: {
+      freeEphemeralFunction(db, (FuncDef*)p4);
+      break;
+    }
+    case P4_MEM: {
+      if( db->pnBytesFreed==0 ){
+        sqlite3ValueFree((sqlite3_value*)p4);
+      }else{
+        Mem *p = (Mem*)p4;
+        if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
+        sqlite3DbFree(db, p);
       }
+      break;
+    }
+    case P4_VTAB : {
+      if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
+      break;
     }
   }
 }
@@ -69151,8 +71318,8 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
 ** Compute a string that describes the P4 parameter for an opcode.
 ** Use zTemp for any required temporary buffer space.
 */
-static char *displayP4(Op *pOp, char *zTemp, int nTemp){
-  char *zP4 = zTemp;
+static const char *displayP4(Op *pOp, char *zTemp, int nTemp){
+  const char *zP4 = zTemp;
   StrAccum x;
   assert( nTemp>=20 );
   sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
@@ -69249,6 +71416,10 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
       zTemp[0] = 0;
       break;
     }
+    case P4_TABLE: {
+      sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
+      break;
+    }
     default: {
       zP4 = pOp->p4.z;
       if( zP4==0 ){
@@ -69348,7 +71519,7 @@ SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
 ** Print a single opcode.  This routine is used for debugging only.
 */
 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
-  char *zP4;
+  const char *zP4;
   char zPtr[50];
   char zCom[100];
   static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
@@ -69427,6 +71598,7 @@ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
     sqlite3VdbeFreeCursor(p->v, apCsr[i]);
   }
   releaseMemArray(aMem, p->nChildMem);
+  sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
   sqlite3DbFree(p->v->db, p);
 }
 
@@ -69469,7 +71641,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
   releaseMemArray(pMem, 8);
   p->pResultSet = 0;
 
-  if( p->rc==SQLITE_NOMEM ){
+  if( p->rc==SQLITE_NOMEM_BKPT ){
     /* This happens if a malloc() inside a call to sqlite3_column_text() or
     ** sqlite3_column_text16() failed.  */
     sqlite3OomFault(db);
@@ -69513,7 +71685,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
     rc = SQLITE_ERROR;
     sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
   }else{
-    char *zP4;
+    const char *zP4;
     Op *pOp;
     if( i<p->nOp ){
       /* The output line number is small enough that we are still in the
@@ -69732,7 +71904,7 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
   p->magic = VDBE_MAGIC_RUN;
 
 #ifdef SQLITE_DEBUG
-  for(i=1; i<p->nMem; i++){
+  for(i=0; i<p->nMem; i++){
     assert( p->aMem[i].db==p->db );
   }
 #endif
@@ -69797,16 +71969,13 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
   nOnce = pParse->nOnce;
   if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
   
-  /* For each cursor required, also allocate a memory cell. Memory
-  ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
-  ** the vdbe program. Instead they are used to allocate memory for
-  ** VdbeCursor/BtCursor structures. The blob of memory associated with 
-  ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
-  ** stores the blob of memory associated with cursor 1, etc.
-  **
+  /* Each cursor uses a memory cell.  The first cursor (cursor 0) can
+  ** use aMem[0] which is not otherwise used by the VDBE program.  Allocate
+  ** space at the end of aMem[] for cursors 1 and greater.
   ** See also: allocateCursor().
   */
   nMem += nCursor;
+  if( nCursor==0 && nMem>0 ) nMem++;  /* Space for aMem[0] even if not used */
 
   /* Figure out how much reusable memory is available at the end of the
   ** opcode array.  This extra memory will be reallocated for other elements
@@ -69868,9 +72037,8 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
   pParse->nzVar =  0;
   pParse->azVar = 0;
   if( p->aMem ){
-    p->aMem--;                      /* aMem[] goes from 1..nMem */
-    p->nMem = nMem;                 /*       not from 0..nMem-1 */
-    for(n=1; n<=nMem; n++){
+    p->nMem = nMem;
+    for(n=0; n<nMem; n++){
       p->aMem[n].flags = MEM_Undefined;
       p->aMem[n].db = db;
     }
@@ -69955,6 +72123,9 @@ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
   v->db->lastRowid = pFrame->lastRowid;
   v->nChange = pFrame->nChange;
   v->db->nChange = pFrame->nDbChange;
+  sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
+  v->pAuxData = pFrame->pAuxData;
+  pFrame->pAuxData = 0;
   return pFrame->pc;
 }
 
@@ -69977,7 +72148,7 @@ static void closeAllCursors(Vdbe *p){
   assert( p->nFrame==0 );
   closeCursorsInFrame(p);
   if( p->aMem ){
-    releaseMemArray(&p->aMem[1], p->nMem);
+    releaseMemArray(p->aMem, p->nMem);
   }
   while( p->pDelFrame ){
     VdbeFrame *pDel = p->pDelFrame;
@@ -69986,7 +72157,7 @@ static void closeAllCursors(Vdbe *p){
   }
 
   /* Delete any auxdata allocations made by the VM */
-  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
+  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
   assert( p->pAuxData==0 );
 }
 
@@ -70002,7 +72173,7 @@ static void Cleanup(Vdbe *p){
   int i;
   if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
   if( p->aMem ){
-    for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
+    for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
   }
 #endif
 
@@ -70058,7 +72229,7 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName(
   assert( var<COLNAME_N );
   if( p->db->mallocFailed ){
     assert( !zName || xDel!=SQLITE_DYNAMIC );
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   assert( p->aColName!=0 );
   pColName = &(p->aColName[idx+var*p->nResColumn]);
@@ -70075,7 +72246,9 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName(
 */
 static int vdbeCommit(sqlite3 *db, Vdbe *p){
   int i;
-  int nTrans = 0;  /* Number of databases with an active write-transaction */
+  int nTrans = 0;  /* Number of databases with an active write-transaction
+                   ** that are candidates for a two-phase commit using a
+                   ** master-journal */
   int rc = SQLITE_OK;
   int needXcommit = 0;
 
@@ -70103,10 +72276,28 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
     Btree *pBt = db->aDb[i].pBt;
     if( sqlite3BtreeIsInTrans(pBt) ){
+      /* Whether or not a database might need a master journal depends upon
+      ** its journal mode (among other things).  This matrix determines which
+      ** journal modes use a master journal and which do not */
+      static const u8 aMJNeeded[] = {
+        /* DELETE   */  1,
+        /* PERSIST   */ 1,
+        /* OFF       */ 0,
+        /* TRUNCATE  */ 1,
+        /* MEMORY    */ 0,
+        /* WAL       */ 0
+      };
+      Pager *pPager;   /* Pager associated with pBt */
       needXcommit = 1;
-      if( i!=1 ) nTrans++;
       sqlite3BtreeEnter(pBt);
-      rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
+      pPager = sqlite3BtreePager(pBt);
+      if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
+       && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
+      ){ 
+        assert( i!=1 );
+        nTrans++;
+      }
+      rc = sqlite3PagerExclusiveLock(pPager);
       sqlite3BtreeLeave(pBt);
     }
   }
@@ -70164,7 +72355,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 #ifndef SQLITE_OMIT_DISKIO
   else{
     sqlite3_vfs *pVfs = db->pVfs;
-    int needSync = 0;
     char *zMaster = 0;   /* File-name for the master journal */
     char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
     sqlite3_file *pMaster = 0;
@@ -70176,7 +72366,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
     /* Select a master journal file name */
     nMainFile = sqlite3Strlen30(zMainFile);
     zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
-    if( zMaster==0 ) return SQLITE_NOMEM;
+    if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
     do {
       u32 iRandom;
       if( retryCount ){
@@ -70224,9 +72414,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
           continue;  /* Ignore TEMP and :memory: databases */
         }
         assert( zFile[0]!=0 );
-        if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
-          needSync = 1;
-        }
         rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
         offset += sqlite3Strlen30(zFile)+1;
         if( rc!=SQLITE_OK ){
@@ -70241,8 +72428,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
     /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
     ** flag is set this is not required.
     */
-    if( needSync 
-     && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
+    if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
      && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
     ){
       sqlite3OsCloseFree(pMaster);
@@ -70278,7 +72464,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
     ** doing this the directory is synced again before any individual
     ** transaction files are deleted.
     */
-    rc = sqlite3OsDelete(pVfs, zMaster, needSync);
+    rc = sqlite3OsDelete(pVfs, zMaster, 1);
     sqlite3DbFree(db, zMaster);
     zMaster = 0;
     if( rc ){
@@ -70466,7 +72652,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
   */
 
   if( db->mallocFailed ){
-    p->rc = SQLITE_NOMEM;
+    p->rc = SQLITE_NOMEM_BKPT;
   }
   if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
   closeAllCursors(p);
@@ -70627,7 +72813,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
   p->magic = VDBE_MAGIC_HALT;
   checkActiveVdbeCnt(db);
   if( db->mallocFailed ){
-    p->rc = SQLITE_NOMEM;
+    p->rc = SQLITE_NOMEM_BKPT;
   }
 
   /* If the auto-commit flag is set to true, then any locks that were held
@@ -70814,8 +73000,7 @@ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
 **    * the corresponding bit in argument mask is clear (where the first
 **      function parameter corresponds to bit 0 etc.).
 */
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
-  AuxData **pp = &pVdbe->pAuxData;
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
   while( *pp ){
     AuxData *pAux = *pp;
     if( (iOp<0)
@@ -70826,7 +73011,7 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
         pAux->xDelete(pAux->pAux);
       }
       *pp = pAux->pNext;
-      sqlite3DbFree(pVdbe->db, pAux);
+      sqlite3DbFree(db, pAux);
     }else{
       pp= &pAux->pNext;
     }
@@ -71425,6 +73610,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
     pMem->db = pKeyInfo->db;
     /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
     pMem->szMalloc = 0;
+    pMem->z = 0;
     d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
     pMem++;
     if( (++u)>=p->nField ) break;
@@ -71605,7 +73791,7 @@ static int vdbeCompareMemString(
     v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
     n2 = v2==0 ? 0 : c2.n;
     rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
-    if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
+    if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
     sqlite3VdbeMemRelease(&c1);
     sqlite3VdbeMemRelease(&c2);
     return rc;
@@ -72405,6 +74591,90 @@ SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+
+/*
+** If the second argument is not NULL, release any allocations associated 
+** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord
+** structure itself, using sqlite3DbFree().
+**
+** This function is used to free UnpackedRecord structures allocated by
+** the vdbeUnpackRecord() function found in vdbeapi.c.
+*/
+static void vdbeFreeUnpacked(sqlite3 *db, UnpackedRecord *p){
+  if( p ){
+    int i;
+    for(i=0; i<p->nField; i++){
+      Mem *pMem = &p->aMem[i];
+      if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
+    }
+    sqlite3DbFree(db, p);
+  }
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call,
+** then cursor passed as the second argument should point to the row about
+** to be update or deleted. If the application calls sqlite3_preupdate_old(),
+** the required value will be read from the row the cursor points to.
+*/
+SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
+  Vdbe *v,                        /* Vdbe pre-update hook is invoked by */
+  VdbeCursor *pCsr,               /* Cursor to grab old.* values from */
+  int op,                         /* SQLITE_INSERT, UPDATE or DELETE */
+  const char *zDb,                /* Database name */
+  Table *pTab,                    /* Modified table */
+  i64 iKey1,                      /* Initial key value */
+  int iReg                        /* Register for new.* record */
+){
+  sqlite3 *db = v->db;
+  i64 iKey2;
+  PreUpdate preupdate;
+  const char *zTbl = pTab->zName;
+  static const u8 fakeSortOrder = 0;
+
+  assert( db->pPreUpdate==0 );
+  memset(&preupdate, 0, sizeof(PreUpdate));
+  if( op==SQLITE_UPDATE ){
+    iKey2 = v->aMem[iReg].u.i;
+  }else{
+    iKey2 = iKey1;
+  }
+
+  assert( pCsr->nField==pTab->nCol 
+       || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
+  );
+
+  preupdate.v = v;
+  preupdate.pCsr = pCsr;
+  preupdate.op = op;
+  preupdate.iNewReg = iReg;
+  preupdate.keyinfo.db = db;
+  preupdate.keyinfo.enc = ENC(db);
+  preupdate.keyinfo.nField = pTab->nCol;
+  preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
+  preupdate.iKey1 = iKey1;
+  preupdate.iKey2 = iKey2;
+  preupdate.iPKey = pTab->iPKey;
+
+  db->pPreUpdate = &preupdate;
+  db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
+  db->pPreUpdate = 0;
+  sqlite3DbFree(db, preupdate.aRecord);
+  vdbeFreeUnpacked(db, preupdate.pUnpacked);
+  vdbeFreeUnpacked(db, preupdate.pNewUnpacked);
+  if( preupdate.aNew ){
+    int i;
+    for(i=0; i<pCsr->nField; i++){
+      sqlite3VdbeMemRelease(&preupdate.aNew[i]);
+    }
+    sqlite3DbFree(db, preupdate.aNew);
+  }
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
 /************** End of vdbeaux.c *********************************************/
 /************** Begin file vdbeapi.c *****************************************/
 /*
@@ -72889,7 +75159,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx
 SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){
   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   sqlite3VdbeMemSetNull(pCtx->pOut);
-  pCtx->isError = SQLITE_NOMEM;
+  pCtx->isError = SQLITE_NOMEM_BKPT;
   pCtx->fErrorOrAux = 1;
   sqlite3OomFault(pCtx->pOut->db);
 }
@@ -72965,7 +75235,7 @@ static int sqlite3Step(Vdbe *p){
   db = p->db;
   if( db->mallocFailed ){
     p->rc = SQLITE_NOMEM;
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 
   if( p->pc<=0 && p->expired ){
@@ -73028,7 +75298,7 @@ static int sqlite3Step(Vdbe *p){
 
   db->errCode = rc;
   if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
-    p->rc = SQLITE_NOMEM;
+    p->rc = SQLITE_NOMEM_BKPT;
   }
 end_of_step:
   /* At this point local variable rc holds the value that should be 
@@ -73095,7 +75365,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
       v->rc = rc2;
     } else {
       v->zErrMsg = 0;
-      v->rc = rc = SQLITE_NOMEM;
+      v->rc = rc = SQLITE_NOMEM_BKPT;
     }
   }
   rc = sqlite3ApiExit(db, rc);
@@ -73720,6 +75990,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
   int nData, 
   void (*xDel)(void*)
 ){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( nData<0 ) return SQLITE_MISUSE_BKPT;
+#endif
   return bindText(pStmt, i, zData, nData, xDel, 0);
 }
 SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
@@ -74025,6 +76298,187 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, i
   return (int)v;
 }
 
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Allocate and populate an UnpackedRecord structure based on the serialized
+** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
+** if successful, or a NULL pointer if an OOM error is encountered.
+*/
+static UnpackedRecord *vdbeUnpackRecord(
+  KeyInfo *pKeyInfo, 
+  int nKey, 
+  const void *pKey
+){
+  char *dummy;                    /* Dummy argument for AllocUnpackedRecord() */
+  UnpackedRecord *pRet;           /* Return value */
+
+  pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo, 0, 0, &dummy);
+  if( pRet ){
+    memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
+    sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
+  }
+  return pRet;
+}
+
+/*
+** This function is called from within a pre-update callback to retrieve
+** a field of the row currently being updated or deleted.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+  PreUpdate *p = db->pPreUpdate;
+  int rc = SQLITE_OK;
+
+  /* Test that this call is being made from within an SQLITE_DELETE or
+  ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
+  if( !p || p->op==SQLITE_INSERT ){
+    rc = SQLITE_MISUSE_BKPT;
+    goto preupdate_old_out;
+  }
+  if( iIdx>=p->pCsr->nField || iIdx<0 ){
+    rc = SQLITE_RANGE;
+    goto preupdate_old_out;
+  }
+
+  /* If the old.* record has not yet been loaded into memory, do so now. */
+  if( p->pUnpacked==0 ){
+    u32 nRec;
+    u8 *aRec;
+
+    rc = sqlite3BtreeDataSize(p->pCsr->uc.pCursor, &nRec);
+    if( rc!=SQLITE_OK ) goto preupdate_old_out;
+    aRec = sqlite3DbMallocRaw(db, nRec);
+    if( !aRec ) goto preupdate_old_out;
+    rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec);
+    if( rc==SQLITE_OK ){
+      p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
+      if( !p->pUnpacked ) rc = SQLITE_NOMEM;
+    }
+    if( rc!=SQLITE_OK ){
+      sqlite3DbFree(db, aRec);
+      goto preupdate_old_out;
+    }
+    p->aRecord = aRec;
+  }
+
+  if( iIdx>=p->pUnpacked->nField ){
+    *ppValue = (sqlite3_value *)columnNullValue();
+  }else{
+    *ppValue = &p->pUnpacked->aMem[iIdx];
+    if( iIdx==p->iPKey ){
+      sqlite3VdbeMemSetInt64(*ppValue, p->iKey1);
+    }
+  }
+
+ preupdate_old_out:
+  sqlite3Error(db, rc);
+  return sqlite3ApiExit(db, rc);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is called from within a pre-update callback to retrieve
+** the number of columns in the row being updated, deleted or inserted.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_count(sqlite3 *db){
+  PreUpdate *p = db->pPreUpdate;
+  return (p ? p->keyinfo.nField : 0);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is designed to be called from within a pre-update callback
+** only. It returns zero if the change that caused the callback was made
+** immediately by a user SQL statement. Or, if the change was made by a
+** trigger program, it returns the number of trigger programs currently
+** on the stack (1 for a top-level trigger, 2 for a trigger fired by a 
+** top-level trigger etc.).
+**
+** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL
+** or SET DEFAULT action is considered a trigger.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_depth(sqlite3 *db){
+  PreUpdate *p = db->pPreUpdate;
+  return (p ? p->v->nFrame : 0);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is called from within a pre-update callback to retrieve
+** a field of the row currently being updated or inserted.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+  PreUpdate *p = db->pPreUpdate;
+  int rc = SQLITE_OK;
+  Mem *pMem;
+
+  if( !p || p->op==SQLITE_DELETE ){
+    rc = SQLITE_MISUSE_BKPT;
+    goto preupdate_new_out;
+  }
+  if( iIdx>=p->pCsr->nField || iIdx<0 ){
+    rc = SQLITE_RANGE;
+    goto preupdate_new_out;
+  }
+
+  if( p->op==SQLITE_INSERT ){
+    /* For an INSERT, memory cell p->iNewReg contains the serialized record
+    ** that is being inserted. Deserialize it. */
+    UnpackedRecord *pUnpack = p->pNewUnpacked;
+    if( !pUnpack ){
+      Mem *pData = &p->v->aMem[p->iNewReg];
+      rc = sqlite3VdbeMemExpandBlob(pData);
+      if( rc!=SQLITE_OK ) goto preupdate_new_out;
+      pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
+      if( !pUnpack ){
+        rc = SQLITE_NOMEM;
+        goto preupdate_new_out;
+      }
+      p->pNewUnpacked = pUnpack;
+    }
+    if( iIdx>=pUnpack->nField ){
+      pMem = (sqlite3_value *)columnNullValue();
+    }else{
+      pMem = &pUnpack->aMem[iIdx];
+      if( iIdx==p->iPKey ){
+        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
+      }
+    }
+  }else{
+    /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
+    ** value. Make a copy of the cell contents and return a pointer to it.
+    ** It is not safe to return a pointer to the memory cell itself as the
+    ** caller may modify the value text encoding.
+    */
+    assert( p->op==SQLITE_UPDATE );
+    if( !p->aNew ){
+      p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
+      if( !p->aNew ){
+        rc = SQLITE_NOMEM;
+        goto preupdate_new_out;
+      }
+    }
+    assert( iIdx>=0 && iIdx<p->pCsr->nField );
+    pMem = &p->aNew[iIdx];
+    if( pMem->flags==0 ){
+      if( iIdx==p->iPKey ){
+        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
+      }else{
+        rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
+        if( rc!=SQLITE_OK ) goto preupdate_new_out;
+      }
+    }
+  }
+  *ppValue = pMem;
+
+ preupdate_new_out:
+  sqlite3Error(db, rc);
+  return sqlite3ApiExit(db, rc);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
 /*
 ** Return status data for a single loop within query pStmt.
@@ -74376,6 +76830,16 @@ static void updateMaxBlobsize(Mem *p){
 #endif
 
 /*
+** This macro evaluates to true if either the update hook or the preupdate
+** hook are enabled for database connect DB.
+*/
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback)
+#else
+# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback)
+#endif
+
+/*
 ** The next global variable is incremented each time the OP_Found opcode
 ** is executed. This is used to test whether or not the foreign key
 ** operation implemented using OP_FkIsZero is working. This variable
@@ -74481,11 +76945,11 @@ static VdbeCursor *allocateCursor(
   **     be freed lazily via the sqlite3_release_memory() API. This
   **     minimizes the number of malloc calls made by the system.
   **
-  ** Memory cells for cursors are allocated at the top of the address
-  ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for
-  ** cursor 1 is managed by memory cell (p->nMem-1), etc.
+  ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from
+  ** the top of the register space.  Cursor 1 is at Mem[p->nMem-1].
+  ** Cursor 2 is at Mem[p->nMem-2]. And so forth.
   */
-  Mem *pMem = &p->aMem[p->nMem-iCur];
+  Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
 
   int nByte;
   VdbeCursor *pCx = 0;
@@ -74493,8 +76957,8 @@ static VdbeCursor *allocateCursor(
       ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + 
       (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
 
-  assert( iCur<p->nCursor );
-  if( p->apCsr[iCur] ){
+  assert( iCur>=0 && iCur<p->nCursor );
+  if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
     sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
     p->apCsr[iCur] = 0;
   }
@@ -74571,7 +77035,7 @@ static void applyAffinity(
   if( affinity>=SQLITE_AFF_NUMERIC ){
     assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
              || affinity==SQLITE_AFF_NUMERIC );
-    if( (pRec->flags & MEM_Int)==0 ){
+    if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
       if( (pRec->flags & MEM_Real)==0 ){
         if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
       }else{
@@ -74581,10 +77045,13 @@ static void applyAffinity(
   }else if( affinity==SQLITE_AFF_TEXT ){
     /* Only attempt the conversion to TEXT if there is an integer or real
     ** representation (blob and NULL do not get converted) but no string
-    ** representation.
-    */
-    if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
-      sqlite3VdbeMemStringify(pRec, enc, 1);
+    ** representation.  It would be harmless to repeat the conversion if 
+    ** there is already a string rep, but it is pointless to waste those
+    ** CPU cycles. */
+    if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
+      if( (pRec->flags&(MEM_Real|MEM_Int)) ){
+        sqlite3VdbeMemStringify(pRec, enc, 1);
+      }
     }
     pRec->flags &= ~(MEM_Real|MEM_Int);
   }
@@ -74913,10 +77380,10 @@ static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){
 static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
   Mem *pOut;
   assert( pOp->p2>0 );
-  assert( pOp->p2<=(p->nMem-p->nCursor) );
+  assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
   pOut = &p->aMem[pOp->p2];
   memAboutToChange(p, pOut);
-  if( VdbeMemDynamic(pOut) ){
+  if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/
     return out2PrereleaseWithClear(pOut);
   }else{
     pOut->flags = MEM_Int;
@@ -75011,7 +77478,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
   }
   sqlite3EndBenignMalloc();
 #endif
-  for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
+  for(pOp=&aOp[p->pc]; 1; pOp++){
+    /* Errors are detected by individual opcodes, with an immediate
+    ** jumps to abort_due_to_error. */
+    assert( rc==SQLITE_OK );
+
     assert( pOp>=aOp && pOp<&aOp[p->nOp]);
 #ifdef VDBE_PROFILE
     start = sqlite3Hwtime();
@@ -75044,37 +77515,39 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
 
     /* Sanity checking on other operands */
 #ifdef SQLITE_DEBUG
-    assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
-    if( (pOp->opflags & OPFLG_IN1)!=0 ){
-      assert( pOp->p1>0 );
-      assert( pOp->p1<=(p->nMem-p->nCursor) );
-      assert( memIsValid(&aMem[pOp->p1]) );
-      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
-      REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
-    }
-    if( (pOp->opflags & OPFLG_IN2)!=0 ){
-      assert( pOp->p2>0 );
-      assert( pOp->p2<=(p->nMem-p->nCursor) );
-      assert( memIsValid(&aMem[pOp->p2]) );
-      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
-      REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
-    }
-    if( (pOp->opflags & OPFLG_IN3)!=0 ){
-      assert( pOp->p3>0 );
-      assert( pOp->p3<=(p->nMem-p->nCursor) );
-      assert( memIsValid(&aMem[pOp->p3]) );
-      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
-      REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
-    }
-    if( (pOp->opflags & OPFLG_OUT2)!=0 ){
-      assert( pOp->p2>0 );
-      assert( pOp->p2<=(p->nMem-p->nCursor) );
-      memAboutToChange(p, &aMem[pOp->p2]);
-    }
-    if( (pOp->opflags & OPFLG_OUT3)!=0 ){
-      assert( pOp->p3>0 );
-      assert( pOp->p3<=(p->nMem-p->nCursor) );
-      memAboutToChange(p, &aMem[pOp->p3]);
+    {
+      u8 opProperty = sqlite3OpcodeProperty[pOp->opcode];
+      if( (opProperty & OPFLG_IN1)!=0 ){
+        assert( pOp->p1>0 );
+        assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
+        assert( memIsValid(&aMem[pOp->p1]) );
+        assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
+        REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
+      }
+      if( (opProperty & OPFLG_IN2)!=0 ){
+        assert( pOp->p2>0 );
+        assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
+        assert( memIsValid(&aMem[pOp->p2]) );
+        assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
+        REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
+      }
+      if( (opProperty & OPFLG_IN3)!=0 ){
+        assert( pOp->p3>0 );
+        assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+        assert( memIsValid(&aMem[pOp->p3]) );
+        assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
+        REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
+      }
+      if( (opProperty & OPFLG_OUT2)!=0 ){
+        assert( pOp->p2>0 );
+        assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
+        memAboutToChange(p, &aMem[pOp->p2]);
+      }
+      if( (opProperty & OPFLG_OUT3)!=0 ){
+        assert( pOp->p3>0 );
+        assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+        memAboutToChange(p, &aMem[pOp->p3]);
+      }
     }
 #endif
 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@@ -75158,7 +77631,7 @@ check_for_interrupt:
     nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
     if( db->xProgress(db->pProgressArg) ){
       rc = SQLITE_INTERRUPT;
-      goto vdbe_error_halt;
+      goto abort_due_to_error;
     }
   }
 #endif
@@ -75172,7 +77645,7 @@ check_for_interrupt:
 ** and then jump to address P2.
 */
 case OP_Gosub: {            /* jump */
-  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
   pIn1 = &aMem[pOp->p1];
   assert( VdbeMemDynamic(pIn1)==0 );
   memAboutToChange(p, pIn1);
@@ -75212,7 +77685,7 @@ case OP_Return: {           /* in1 */
 ** See also: EndCoroutine
 */
 case OP_InitCoroutine: {     /* jump */
-  assert( pOp->p1>0 &&  pOp->p1<=(p->nMem-p->nCursor) );
+  assert( pOp->p1>0 &&  pOp->p1<=(p->nMem+1 - p->nCursor) );
   assert( pOp->p2>=0 && pOp->p2<p->nOp );
   assert( pOp->p3>=0 && pOp->p3<p->nOp );
   pOut = &aMem[pOp->p1];
@@ -75314,8 +77787,6 @@ case OP_HaltIfNull: {      /* in3 */
 ** is the same as executing Halt.
 */
 case OP_Halt: {
-  const char *zType;
-  const char *zLogFmt;
   VdbeFrame *pFrame;
   int pcx;
 
@@ -75344,34 +77815,28 @@ case OP_Halt: {
   p->rc = pOp->p1;
   p->errorAction = (u8)pOp->p2;
   p->pc = pcx;
+  assert( pOp->p5>=0 && pOp->p5<=4 );
   if( p->rc ){
     if( pOp->p5 ){
       static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
                                              "FOREIGN KEY" };
-      assert( pOp->p5>=1 && pOp->p5<=4 );
       testcase( pOp->p5==1 );
       testcase( pOp->p5==2 );
       testcase( pOp->p5==3 );
       testcase( pOp->p5==4 );
-      zType = azType[pOp->p5-1];
+      sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
+      if( pOp->p4.z ){
+        p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
+      }
     }else{
-      zType = 0;
-    }
-    assert( zType!=0 || pOp->p4.z!=0 );
-    zLogFmt = "abort at %d in [%s]: %s";
-    if( zType && pOp->p4.z ){
-      sqlite3VdbeError(p, "%s constraint failed: %s", zType, pOp->p4.z);
-    }else if( pOp->p4.z ){
       sqlite3VdbeError(p, "%s", pOp->p4.z);
-    }else{
-      sqlite3VdbeError(p, "%s constraint failed", zType);
     }
-    sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
+    sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
   }
   rc = sqlite3VdbeHalt(p);
   assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
   if( rc==SQLITE_BUSY ){
-    p->rc = rc = SQLITE_BUSY;
+    p->rc = SQLITE_BUSY;
   }else{
     assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
     assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
@@ -75437,7 +77902,7 @@ case OP_String8: {         /* same as TK_STRING, out2 */
 #ifndef SQLITE_OMIT_UTF16
   if( encoding!=SQLITE_UTF8 ){
     rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
-    if( rc==SQLITE_TOOBIG ) goto too_big;
+    assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG );
     if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
     assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
     assert( VdbeMemDynamic(pOut)==0 );
@@ -75450,10 +77915,12 @@ case OP_String8: {         /* same as TK_STRING, out2 */
     pOp->p4.z = pOut->z;
     pOp->p1 = pOut->n;
   }
+  testcase( rc==SQLITE_TOOBIG );
 #endif
   if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
   }
+  assert( rc==SQLITE_OK );
   /* Fall through to the next case, OP_String */
 }
   
@@ -75462,10 +77929,12 @@ case OP_String8: {         /* same as TK_STRING, out2 */
 **
 ** The string value P4 of length P1 (bytes) is stored in register P2.
 **
-** If P5!=0 and the content of register P3 is greater than zero, then
+** If P3 is not zero and the content of register P3 is equal to P5, then
 ** the datatype of the register P2 is converted to BLOB.  The content is
 ** the same sequence of bytes, it is merely interpreted as a BLOB instead
-** of a string, as if it had been CAST.
+** of a string, as if it had been CAST.  In other words:
+**
+** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB)
 */
 case OP_String: {          /* out2 */
   assert( pOp->p4.z!=0 );
@@ -75476,12 +77945,11 @@ case OP_String: {          /* out2 */
   pOut->enc = encoding;
   UPDATE_MAX_BLOBSIZE(pOut);
 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
-  if( pOp->p5 ){
-    assert( pOp->p3>0 );
-    assert( pOp->p3<=(p->nMem-p->nCursor) );
+  if( pOp->p3>0 ){
+    assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
     pIn3 = &aMem[pOp->p3];
     assert( pIn3->flags & MEM_Int );
-    if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
+    if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
   }
 #endif
   break;
@@ -75504,7 +77972,7 @@ case OP_Null: {           /* out2 */
   u16 nullFlag;
   pOut = out2Prerelease(p, pOp);
   cnt = pOp->p3-pOp->p2;
-  assert( pOp->p3<=(p->nMem-p->nCursor) );
+  assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
   pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
   while( cnt>0 ){
     pOut++;
@@ -75525,7 +77993,7 @@ case OP_Null: {           /* out2 */
 ** previously copied using OP_SCopy, the copies will continue to be valid.
 */
 case OP_SoftNull: {
-  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
   pOut = &aMem[pOp->p1];
   pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined;
   break;
@@ -75592,8 +78060,8 @@ case OP_Move: {
   pIn1 = &aMem[p1];
   pOut = &aMem[p2];
   do{
-    assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
-    assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
+    assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] );
+    assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] );
     assert( memIsValid(pIn1) );
     memAboutToChange(p, pOut);
     sqlite3VdbeMemMove(pOut, pIn1);
@@ -75693,7 +78161,7 @@ case OP_ResultRow: {
   int i;
   assert( p->nResColumn==pOp->p2 );
   assert( pOp->p1>0 );
-  assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 );
+  assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
 
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
   /* Run the progress counter just before returning.
@@ -75703,7 +78171,7 @@ case OP_ResultRow: {
    && db->xProgress(db->pProgressArg)!=0
   ){
     rc = SQLITE_INTERRUPT;
-    goto vdbe_error_halt;
+    goto abort_due_to_error;
   }
 #endif
 
@@ -75713,7 +78181,7 @@ case OP_ResultRow: {
   if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
     assert( db->flags&SQLITE_CountRows );
     assert( p->usesStmtJournal );
-    break;
+    goto abort_due_to_error;
   }
 
   /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then 
@@ -75733,9 +78201,7 @@ case OP_ResultRow: {
   */
   assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
   rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
-  if( NEVER(rc!=SQLITE_OK) ){
-    break;
-  }
+  assert( rc==SQLITE_OK );
 
   /* Invalidate all ephemeral cursor row caches */
   p->cacheCtr = (p->cacheCtr + 2)|1;
@@ -76007,8 +78473,8 @@ case OP_Function0: {
 
   assert( pOp->p4type==P4_FUNCDEF );
   n = pOp->p5;
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
-  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
   assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
   pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
   if( pCtx==0 ) goto no_mem;
@@ -76058,7 +78524,8 @@ case OP_Function: {
       sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
       rc = pCtx->isError;
     }
-    sqlite3VdbeDeleteAuxData(p, pCtx->iOp, pOp->p1);
+    sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
+    if( rc ) goto abort_due_to_error;
   }
 
   /* Copy the result of the function into register P3 */
@@ -76242,6 +78709,7 @@ case OP_Cast: {                  /* in1 */
   rc = ExpandBlob(pIn1);
   sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
   UPDATE_MAX_BLOBSIZE(pIn1);
+  if( rc ) goto abort_due_to_error;
   break;
 }
 #endif /* SQLITE_OMIT_CAST */
@@ -76383,11 +78851,13 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
     /* Neither operand is NULL.  Do a comparison. */
     affinity = pOp->p5 & SQLITE_AFF_MASK;
     if( affinity>=SQLITE_AFF_NUMERIC ){
-      if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
-        applyNumericAffinity(pIn1,0);
-      }
-      if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
-        applyNumericAffinity(pIn3,0);
+      if( (flags1 | flags3)&MEM_Str ){
+        if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+          applyNumericAffinity(pIn1,0);
+        }
+        if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+          applyNumericAffinity(pIn3,0);
+        }
       }
     }else if( affinity==SQLITE_AFF_TEXT ){
       if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
@@ -76506,11 +78976,11 @@ case OP_Compare: {
   if( aPermute ){
     int k, mx = 0;
     for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
-    assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 );
-    assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 );
+    assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 );
+    assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 );
   }else{
-    assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 );
-    assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 );
+    assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 );
+    assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 );
   }
 #endif /* SQLITE_DEBUG */
   for(i=0; i<n; i++){
@@ -76772,7 +79242,7 @@ case OP_Column: {
   /* If the cursor cache is stale, bring it up-to-date */
   rc = sqlite3VdbeCursorMoveto(&pC, &p2);
 
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
   pDest = &aMem[pOp->p3];
   memAboutToChange(p, pDest);
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -76851,7 +79321,7 @@ case OP_Column: {
       */
       if( offset > 98307 || offset > pC->payloadSize ){
         rc = SQLITE_CORRUPT_BKPT;
-        goto op_column_error;
+        goto abort_due_to_error;
       }
     }
 
@@ -76876,7 +79346,7 @@ case OP_Column: {
       if( pC->aRow==0 ){
         memset(&sMem, 0, sizeof(sMem));
         rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
-        if( rc!=SQLITE_OK ) goto op_column_error;
+        if( rc!=SQLITE_OK ) goto abort_due_to_error;
         zData = (u8*)sMem.z;
       }else{
         zData = pC->aRow;
@@ -76901,7 +79371,6 @@ case OP_Column: {
       }while( i<=p2 && zHdr<zEndHdr );
       pC->nHdrParsed = i;
       pC->iHdrOffset = (u32)(zHdr - zData);
-      if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
   
       /* The record is corrupt if any of the following are true:
       ** (1) the bytes of the header extend past the declared header size
@@ -76911,9 +79380,12 @@ case OP_Column: {
       if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
        || (offset64 > pC->payloadSize)
       ){
+        if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
         rc = SQLITE_CORRUPT_BKPT;
-        goto op_column_error;
+        goto abort_due_to_error;
       }
+      if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
+
     }else{
       t = 0;
     }
@@ -76985,15 +79457,13 @@ case OP_Column: {
     }else{
       rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
                                    pDest);
-      if( rc==SQLITE_OK ){
-        sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
-        pDest->flags &= ~MEM_Ephem;
-      }
+      if( rc!=SQLITE_OK ) goto abort_due_to_error;
+      sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
+      pDest->flags &= ~MEM_Ephem;
     }
   }
 
 op_column_out:
-op_column_error:
   UPDATE_MAX_BLOBSIZE(pDest);
   REGISTER_TRACE(pOp->p3, pDest);
   break;
@@ -77017,7 +79487,7 @@ case OP_Affinity: {
   assert( zAffinity[pOp->p2]==0 );
   pIn1 = &aMem[pOp->p1];
   while( (cAff = *(zAffinity++))!=0 ){
-    assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] );
+    assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
     assert( memIsValid(pIn1) );
     applyAffinity(pIn1, cAff, encoding);
     pIn1++;
@@ -77079,7 +79549,7 @@ case OP_MakeRecord: {
   nZero = 0;         /* Number of zero bytes at the end of the record */
   nField = pOp->p1;
   zAffinity = pOp->p4.z;
-  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 );
+  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
   pData0 = &aMem[nField];
   nField = pOp->p2;
   pLast = &pData0[nField-1];
@@ -77120,7 +79590,9 @@ case OP_MakeRecord: {
     testcase( serial_type==127 );
     testcase( serial_type==128 );
     nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
-  }while( (--pRec)>=pData0 );
+    if( pRec==pData0 ) break;
+    pRec--;
+  }while(1);
 
   /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
   ** which determines the total number of bytes in the header. The varint
@@ -77169,7 +79641,7 @@ case OP_MakeRecord: {
   assert( i==nHdr );
   assert( j==nByte );
 
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
   pOut->n = (int)nByte;
   pOut->flags = MEM_Blob;
   if( nZero ){
@@ -77198,6 +79670,7 @@ case OP_Count: {         /* out2 */
   assert( pCrsr );
   nEntry = 0;  /* Not needed.  Only used to silence a warning. */
   rc = sqlite3BtreeCount(pCrsr, &nEntry);
+  if( rc ) goto abort_due_to_error;
   pOut = out2Prerelease(p, pOp);
   pOut->u.i = nEntry;
   break;
@@ -77267,7 +79740,7 @@ case OP_Savepoint: {
         }else{
           db->nSavepoint++;
         }
-    
+
         /* Link the new savepoint into the database handle's list. */
         pNew->pNext = db->pSavepoint;
         db->pSavepoint = pNew;
@@ -77375,6 +79848,7 @@ case OP_Savepoint: {
       }
     }
   }
+  if( rc ) goto abort_due_to_error;
 
   break;
 }
@@ -77411,7 +79885,7 @@ case OP_AutoCommit: {
       sqlite3VdbeError(p, "cannot commit transaction - "
                           "SQL statements in progress");
       rc = SQLITE_BUSY;
-      break;
+      goto abort_due_to_error;
     }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
       goto vdbe_return;
     }else{
@@ -77438,6 +79912,7 @@ case OP_AutoCommit: {
                    "cannot commit - no transaction is active"));
          
     rc = SQLITE_ERROR;
+    goto abort_due_to_error;
   }
   break;
 }
@@ -77560,6 +80035,7 @@ case OP_Transaction: {
     p->expired = 1;
     rc = SQLITE_SCHEMA;
   }
+  if( rc ) goto abort_due_to_error;
   break;
 }
 
@@ -77629,6 +80105,7 @@ case OP_SetCookie: {
     sqlite3ExpirePreparedStatements(db);
     p->expired = 0;
   }
+  if( rc ) goto abort_due_to_error;
   break;
 }
 
@@ -77726,7 +80203,7 @@ case OP_OpenWrite:
 
   if( p->expired ){
     rc = SQLITE_ABORT_ROLLBACK;
-    break;
+    goto abort_due_to_error;
   }
 
   nField = 0;
@@ -77750,7 +80227,7 @@ case OP_OpenWrite:
   }
   if( pOp->p5 & OPFLAG_P2ISREG ){
     assert( p2>0 );
-    assert( p2<=(p->nMem-p->nCursor) );
+    assert( p2<=(p->nMem+1 - p->nCursor) );
     pIn2 = &aMem[p2];
     assert( memIsValid(pIn2) );
     assert( (pIn2->flags & MEM_Int)!=0 );
@@ -77760,10 +80237,7 @@ case OP_OpenWrite:
     ** that opcode will always set the p2 value to 2 or more or else fail.
     ** If there were a failure, the prepared statement would have halted
     ** before reaching this instruction. */
-    if( NEVER(p2<2) ) {
-      rc = SQLITE_CORRUPT_BKPT;
-      goto abort_due_to_error;
-    }
+    assert( p2>=2 );
   }
   if( pOp->p4type==P4_KEYINFO ){
     pKeyInfo = pOp->p4.pKeyInfo;
@@ -77801,6 +80275,7 @@ open_cursor_set_hints:
 #endif
   sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
                                (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
+  if( rc ) goto abort_due_to_error;
   break;
 }
 
@@ -77877,6 +80352,7 @@ case OP_OpenEphemeral: {
       pCx->isTable = 1;
     }
   }
+  if( rc ) goto abort_due_to_error;
   pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
   break;
 }
@@ -77902,6 +80378,7 @@ case OP_SorterOpen: {
   assert( pCx->pKeyInfo->db==db );
   assert( pCx->pKeyInfo->enc==ENC(db) );
   rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
+  if( rc ) goto abort_due_to_error;
   break;
 }
 
@@ -78364,7 +80841,7 @@ case OP_Found: {        /* jump, in3 */
   rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
   sqlite3DbFree(db, pFree);
   if( rc!=SQLITE_OK ){
-    break;
+    goto abort_due_to_error;
   }
   pC->seekResult = res;
   alreadyExists = (res==0);
@@ -78436,6 +80913,7 @@ case OP_NotExists: {        /* jump, in3 */
       goto jump_to_p2;
     }
   }
+  if( rc ) goto abort_due_to_error;
   break;
 }
 
@@ -78544,7 +81022,7 @@ case OP_NewRowid: {           /* out2 */
         pMem = &pFrame->aMem[pOp->p3];
       }else{
         /* Assert that P3 is a valid memory cell. */
-        assert( pOp->p3<=(p->nMem-p->nCursor) );
+        assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
         pMem = &aMem[pOp->p3];
         memAboutToChange(p, pMem);
       }
@@ -78578,7 +81056,8 @@ case OP_NewRowid: {           /* out2 */
                                                  0, &res))==SQLITE_OK)
             && (res==0)
             && (++cnt<100));
-      if( rc==SQLITE_OK && res==0 ){
+      if( rc ) goto abort_due_to_error;
+      if( res==0 ){
         rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
         goto abort_due_to_error;
       }
@@ -78618,9 +81097,9 @@ case OP_NewRowid: {           /* out2 */
 ** is part of an INSERT operation.  The difference is only important to
 ** the update hook.
 **
-** Parameter P4 may point to a string containing the table-name, or
-** may be NULL. If it is not NULL, then the update-hook 
-** (sqlite3.xUpdateCallback) is invoked following a successful insert.
+** Parameter P4 may point to a Table structure, or may be NULL. If it is 
+** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked 
+** following a successful insert.
 **
 ** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
 ** allocated, then ownership of P2 is transferred to the pseudo-cursor
@@ -78646,9 +81125,10 @@ case OP_InsertInt: {
   int nZero;        /* Number of zero-bytes to append */
   int seekResult;   /* Result of prior seek or 0 if no USESEEKRESULT flag */
   const char *zDb;  /* database name - used by the update hook */
-  const char *zTbl; /* Table name - used by the opdate hook */
+  Table *pTab;      /* Table structure - used by update and pre-update hooks */
   int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
 
+  op = 0;
   pData = &aMem[pOp->p2];
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   assert( memIsValid(pData) );
@@ -78657,6 +81137,7 @@ case OP_InsertInt: {
   assert( pC->eCurType==CURTYPE_BTREE );
   assert( pC->uc.pCursor!=0 );
   assert( pC->isTable );
+  assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
   REGISTER_TRACE(pOp->p2, pData);
 
   if( pOp->opcode==OP_Insert ){
@@ -78670,6 +81151,28 @@ case OP_InsertInt: {
     iKey = pOp->p3;
   }
 
+  if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
+    assert( pC->isTable );
+    assert( pC->iDb>=0 );
+    zDb = db->aDb[pC->iDb].zName;
+    pTab = pOp->p4.pTab;
+    assert( HasRowid(pTab) );
+    op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+  }else{
+    pTab = 0; /* Not needed.  Silence a comiler warning. */
+    zDb = 0;  /* Not needed.  Silence a compiler warning. */
+  }
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+  /* Invoke the pre-update hook, if any */
+  if( db->xPreUpdateCallback 
+   && pOp->p4type==P4_TABLE
+   && !(pOp->p5 & OPFLAG_ISUPDATE)
+  ){
+    sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2);
+  }
+#endif
+
   if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
   if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey;
   if( pData->flags & MEM_Null ){
@@ -78692,18 +81195,14 @@ case OP_InsertInt: {
   pC->cacheStatus = CACHE_STALE;
 
   /* Invoke the update-hook if required. */
-  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
-    zDb = db->aDb[pC->iDb].zName;
-    zTbl = pOp->p4.z;
-    op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
-    assert( pC->isTable );
-    db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
-    assert( pC->iDb>=0 );
+  if( rc ) goto abort_due_to_error;
+  if( db->xUpdateCallback && op ){
+    db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey);
   }
   break;
 }
 
-/* Opcode: Delete P1 P2 * P4 P5
+/* Opcode: Delete P1 P2 P3 P4 P5
 **
 ** Delete the record at which the P1 cursor is currently pointing.
 **
@@ -78727,15 +81226,24 @@ case OP_InsertInt: {
 ** P1 must not be pseudo-table.  It has to be a real table with
 ** multiple rows.
 **
-** If P4 is not NULL, then it is the name of the table that P1 is
-** pointing to.  The update hook will be invoked, if it exists.
-** If P4 is not NULL then the P1 cursor must have been positioned
-** using OP_NotFound prior to invoking this opcode.
+** If P4 is not NULL then it points to a Table struture. In this case either 
+** the update or pre-update hook, or both, may be invoked. The P1 cursor must
+** have been positioned using OP_NotFound prior to invoking this opcode in 
+** this case. Specifically, if one is configured, the pre-update hook is 
+** invoked if P4 is not NULL. The update-hook is invoked if one is configured, 
+** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
+**
+** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address
+** of the memory cell that contains the value that the rowid of the row will
+** be set to by the update.
 */
 case OP_Delete: {
   VdbeCursor *pC;
-  u8 hasUpdateCallback;
+  const char *zDb;
+  Table *pTab;
+  int opflags;
 
+  opflags = pOp->p2;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
@@ -78743,22 +81251,48 @@ case OP_Delete: {
   assert( pC->uc.pCursor!=0 );
   assert( pC->deferredMoveto==0 );
 
-  hasUpdateCallback = db->xUpdateCallback && pOp->p4.z && pC->isTable;
-  if( pOp->p5 && hasUpdateCallback ){
-    sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
-  }
-
 #ifdef SQLITE_DEBUG
-  /* The seek operation that positioned the cursor prior to OP_Delete will
-  ** have also set the pC->movetoTarget field to the rowid of the row that
-  ** is being deleted */
-  if( pOp->p4.z && pC->isTable && pOp->p5==0 ){
+  if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
+    /* If p5 is zero, the seek operation that positioned the cursor prior to
+    ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
+    ** the row that is being deleted */
     i64 iKey = 0;
     sqlite3BtreeKeySize(pC->uc.pCursor, &iKey);
-    assert( pC->movetoTarget==iKey ); 
+    assert( pC->movetoTarget==iKey );
   }
 #endif
 
+  /* If the update-hook or pre-update-hook will be invoked, set zDb to
+  ** the name of the db to pass as to it. Also set local pTab to a copy
+  ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
+  ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set 
+  ** VdbeCursor.movetoTarget to the current rowid.  */
+  if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
+    assert( pC->iDb>=0 );
+    assert( pOp->p4.pTab!=0 );
+    zDb = db->aDb[pC->iDb].zName;
+    pTab = pOp->p4.pTab;
+    if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
+      sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
+    }
+  }else{
+    zDb = 0;   /* Not needed.  Silence a compiler warning. */
+    pTab = 0;  /* Not needed.  Silence a compiler warning. */
+  }
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+  /* Invoke the pre-update-hook if required. */
+  if( db->xPreUpdateCallback && pOp->p4.pTab && HasRowid(pTab) ){
+    assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) );
+    sqlite3VdbePreUpdateHook(p, pC,
+        (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, 
+        zDb, pTab, pC->movetoTarget,
+        pOp->p3
+    );
+  }
+  if( opflags & OPFLAG_ISNOOP ) break;
+#endif
   /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ 
   assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 );
   assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
@@ -78780,14 +81314,18 @@ case OP_Delete: {
 
   rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
   pC->cacheStatus = CACHE_STALE;
+  if( rc ) goto abort_due_to_error;
 
   /* Invoke the update-hook if required. */
-  if( rc==SQLITE_OK && hasUpdateCallback ){
-    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
-                        db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
-    assert( pC->iDb>=0 );
+  if( opflags & OPFLAG_NCHANGE ){
+    p->nChange++;
+    if( db->xUpdateCallback && HasRowid(pTab) ){
+      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
+          pC->movetoTarget);
+      assert( pC->iDb>=0 );
+    }
   }
-  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
+
   break;
 }
 /* Opcode: ResetCount * * * * *
@@ -78831,6 +81369,7 @@ case OP_SorterCompare: {
   res = 0;
   rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
   VdbeBranchTaken(res!=0,2);
+  if( rc ) goto abort_due_to_error;
   if( res ) goto jump_to_p2;
   break;
 };
@@ -78856,6 +81395,7 @@ case OP_SorterData: {
   rc = sqlite3VdbeSorterRowkey(pC, pOut);
   assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+  if( rc ) goto abort_due_to_error;
   p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
   break;
 }
@@ -78944,6 +81484,7 @@ case OP_RowData: {
   }else{
     rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
   }
+  if( rc ) goto abort_due_to_error;
   pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
   UPDATE_MAX_BLOBSIZE(pOut);
   REGISTER_TRACE(pOp->p2, pOut);
@@ -78984,6 +81525,7 @@ case OP_Rowid: {                 /* out2 */
     assert( pModule->xRowid );
     rc = pModule->xRowid(pC->uc.pVCur, &v);
     sqlite3VtabImportErrmsg(p, pVtab);
+    if( rc ) goto abort_due_to_error;
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
   }else{
     assert( pC->eCurType==CURTYPE_BTREE );
@@ -79054,6 +81596,7 @@ case OP_Last: {        /* jump */
 #ifdef SQLITE_DEBUG
   pC->seekOp = OP_Last;
 #endif
+  if( rc ) goto abort_due_to_error;
   if( pOp->p2>0 ){
     VdbeBranchTaken(res!=0,2);
     if( res ) goto jump_to_p2;
@@ -79118,6 +81661,7 @@ case OP_Rewind: {        /* jump */
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
   }
+  if( rc ) goto abort_due_to_error;
   pC->nullRow = (u8)res;
   assert( pOp->p2>0 && pOp->p2<p->nOp );
   VdbeBranchTaken(res!=0,2);
@@ -79230,6 +81774,7 @@ case OP_Next:          /* jump */
 next_tail:
   pC->cacheStatus = CACHE_STALE;
   VdbeBranchTaken(res==0,2);
+  if( rc ) goto abort_due_to_error;
   if( res==0 ){
     pC->nullRow = 0;
     p->aCounter[pOp->p5]++;
@@ -79280,19 +81825,19 @@ case OP_IdxInsert: {        /* in2 */
   assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
   assert( pC->isTable==0 );
   rc = ExpandBlob(pIn2);
-  if( rc==SQLITE_OK ){
-    if( pOp->opcode==OP_SorterInsert ){
-      rc = sqlite3VdbeSorterWrite(pC, pIn2);
-    }else{
-      nKey = pIn2->n;
-      zKey = pIn2->z;
-      rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3, 
-          ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
-          );
-      assert( pC->deferredMoveto==0 );
-      pC->cacheStatus = CACHE_STALE;
-    }
+  if( rc ) goto abort_due_to_error;
+  if( pOp->opcode==OP_SorterInsert ){
+    rc = sqlite3VdbeSorterWrite(pC, pIn2);
+  }else{
+    nKey = pIn2->n;
+    zKey = pIn2->z;
+    rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3, 
+        ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+        );
+    assert( pC->deferredMoveto==0 );
+    pC->cacheStatus = CACHE_STALE;
   }
+  if( rc) goto abort_due_to_error;
   break;
 }
 
@@ -79310,7 +81855,7 @@ case OP_IdxDelete: {
   UnpackedRecord r;
 
   assert( pOp->p3>0 );
-  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
+  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 );
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
@@ -79323,8 +81868,10 @@ case OP_IdxDelete: {
   r.default_rc = 0;
   r.aMem = &aMem[pOp->p2];
   rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
-  if( rc==SQLITE_OK && res==0 ){
+  if( rc ) goto abort_due_to_error;
+  if( res==0 ){
     rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
+    if( rc ) goto abort_due_to_error;
   }
   assert( pC->deferredMoveto==0 );
   pC->cacheStatus = CACHE_STALE;
@@ -79499,6 +82046,7 @@ case OP_IdxGE:  {       /* jump */
     res++;
   }
   VdbeBranchTaken(res>0,2);
+  if( rc ) goto abort_due_to_error;
   if( res>0 ) goto jump_to_p2;
   break;
 }
@@ -79534,6 +82082,7 @@ case OP_Destroy: {     /* out2 */
   if( db->nVdbeRead > db->nVDestroy+1 ){
     rc = SQLITE_LOCKED;
     p->errorAction = OE_Abort;
+    goto abort_due_to_error;
   }else{
     iDb = pOp->p3;
     assert( DbMaskTest(p->btreeMask, iDb) );
@@ -79541,8 +82090,9 @@ case OP_Destroy: {     /* out2 */
     rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
     pOut->flags = MEM_Int;
     pOut->u.i = iMoved;
+    if( rc ) goto abort_due_to_error;
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    if( rc==SQLITE_OK && iMoved!=0 ){
+    if( iMoved!=0 ){
       sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
       /* All OP_Destroy operations occur on the same btree */
       assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
@@ -79588,6 +82138,7 @@ case OP_Clear: {
       aMem[pOp->p3].u.i += nChange;
     }
   }
+  if( rc ) goto abort_due_to_error;
   break;
 }
 
@@ -79611,6 +82162,7 @@ case OP_ResetSorter: {
     assert( pC->eCurType==CURTYPE_BTREE );
     assert( pC->isEphemeral );
     rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
+    if( rc ) goto abort_due_to_error;
   }
   break;
 }
@@ -79659,6 +82211,7 @@ case OP_CreateTable: {          /* out2 */
     flags = BTREE_BLOBKEY;
   }
   rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
+  if( rc ) goto abort_due_to_error;
   pOut->u.i = pgno;
   break;
 }
@@ -79699,7 +82252,7 @@ case OP_ParseSchema: {
        "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
        db->aDb[iDb].zName, zMaster, pOp->p4.z);
     if( zSql==0 ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }else{
       assert( db->init.busy==0 );
       db->init.busy = 1;
@@ -79711,9 +82264,12 @@ case OP_ParseSchema: {
       db->init.busy = 0;
     }
   }
-  if( rc ) sqlite3ResetAllSchemasOfConnection(db);
-  if( rc==SQLITE_NOMEM ){
-    goto no_mem;
+  if( rc ){
+    sqlite3ResetAllSchemasOfConnection(db);
+    if( rc==SQLITE_NOMEM ){
+      goto no_mem;
+    }
+    goto abort_due_to_error;
   }
   break;  
 }
@@ -79728,6 +82284,7 @@ case OP_ParseSchema: {
 case OP_LoadAnalysis: {
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   rc = sqlite3AnalysisLoad(db, pOp->p1);
+  if( rc ) goto abort_due_to_error;
   break;  
 }
 #endif /* !defined(SQLITE_OMIT_ANALYZE) */
@@ -79773,7 +82330,7 @@ case OP_DropTrigger: {
 
 
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/* Opcode: IntegrityCk P1 P2 P3 * P5
+/* Opcode: IntegrityCk P1 P2 P3 P4 P5
 **
 ** Do an analysis of the currently open database.  Store in
 ** register P1 the text of an error message describing any problems.
@@ -79784,9 +82341,8 @@ case OP_DropTrigger: {
 ** In other words, the analysis stops as soon as reg(P1) errors are 
 ** seen.  Reg(P1) is updated with the number of errors remaining.
 **
-** The root page numbers of all tables in the database are integer
-** stored in reg(P1), reg(P1+1), reg(P1+2), ....  There are P2 tables
-** total.
+** The root page numbers of all tables in the database are integers
+** stored in P4_INTARRAY argument.
 **
 ** If P5 is not zero, the check is done on the auxiliary database
 ** file, not the main database file.
@@ -79796,30 +82352,24 @@ case OP_DropTrigger: {
 case OP_IntegrityCk: {
   int nRoot;      /* Number of tables to check.  (Number of root pages.) */
   int *aRoot;     /* Array of rootpage numbers for tables to be checked */
-  int j;          /* Loop counter */
   int nErr;       /* Number of errors reported */
   char *z;        /* Text of the error report */
   Mem *pnErr;     /* Register keeping track of errors remaining */
 
   assert( p->bIsReader );
   nRoot = pOp->p2;
+  aRoot = pOp->p4.ai;
   assert( nRoot>0 );
-  aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(nRoot+1) );
-  if( aRoot==0 ) goto no_mem;
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+  assert( aRoot[nRoot]==0 );
+  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
   pnErr = &aMem[pOp->p3];
   assert( (pnErr->flags & MEM_Int)!=0 );
   assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
   pIn1 = &aMem[pOp->p1];
-  for(j=0; j<nRoot; j++){
-    aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]);
-  }
-  aRoot[j] = 0;
   assert( pOp->p5<db->nDb );
   assert( DbMaskTest(p->btreeMask, pOp->p5) );
   z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
                                  (int)pnErr->u.i, &nErr);
-  sqlite3DbFree(db, aRoot);
   pnErr->u.i -= nErr;
   sqlite3VdbeMemSetNull(pIn1);
   if( nErr==0 ){
@@ -79987,7 +82537,7 @@ case OP_Program: {        /* jump */
   if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
     rc = SQLITE_ERROR;
     sqlite3VdbeError(p, "too many levels of trigger recursion");
-    break;
+    goto abort_due_to_error;
   }
 
   /* Register pRt is used to store the memory required to save the state
@@ -80001,6 +82551,8 @@ case OP_Program: {        /* jump */
     ** variable nMem (and later, VdbeFrame.nChildMem) to this value.
     */
     nMem = pProgram->nMem + pProgram->nCsr;
+    assert( nMem>0 );
+    if( pProgram->nCsr==0 ) nMem++;
     nByte = ROUND8(sizeof(VdbeFrame))
               + nMem * sizeof(Mem)
               + pProgram->nCsr * sizeof(VdbeCursor *)
@@ -80037,7 +82589,8 @@ case OP_Program: {        /* jump */
     }
   }else{
     pFrame = pRt->u.pFrame;
-    assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
+    assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem 
+        || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
     assert( pProgram->nCsr==pFrame->nChildCsr );
     assert( (int)(pOp - aOp)==pFrame->pc );
   }
@@ -80047,12 +82600,15 @@ case OP_Program: {        /* jump */
   pFrame->lastRowid = lastRowid;
   pFrame->nChange = p->nChange;
   pFrame->nDbChange = p->db->nChange;
+  assert( pFrame->pAuxData==0 );
+  pFrame->pAuxData = p->pAuxData;
+  p->pAuxData = 0;
   p->nChange = 0;
   p->pFrame = pFrame;
-  p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
+  p->aMem = aMem = VdbeFrameMem(pFrame);
   p->nMem = pFrame->nChildMem;
   p->nCursor = (u16)pFrame->nChildCsr;
-  p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
+  p->apCsr = (VdbeCursor **)&aMem[p->nMem];
   p->aOp = aOp = pProgram->aOp;
   p->nOp = pProgram->nOp;
   p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
@@ -80249,21 +82805,6 @@ case OP_DecrJumpZero: {      /* jump, in1 */
 }
 
 
-/* Opcode: JumpZeroIncr P1 P2 * * *
-** Synopsis: if (r[P1]++)==0 ) goto P2
-**
-** The register P1 must contain an integer.  If register P1 is initially
-** zero, then jump to P2.  Increment register P1 regardless of whether or
-** not the jump is taken.
-*/
-case OP_JumpZeroIncr: {        /* jump, in1 */
-  pIn1 = &aMem[pOp->p1];
-  assert( pIn1->flags&MEM_Int );
-  VdbeBranchTaken(pIn1->u.i==0, 2);
-  if( (pIn1->u.i++)==0 ) goto jump_to_p2;
-  break;
-}
-
 /* Opcode: AggStep0 * P2 P3 P4 P5
 ** Synopsis: accum=r[P3] step(r[P2@P5])
 **
@@ -80298,8 +82839,8 @@ case OP_AggStep0: {
 
   assert( pOp->p4type==P4_FUNCDEF );
   n = pOp->p5;
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
-  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
   assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
   pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
   if( pCtx==0 ) goto no_mem;
@@ -80351,6 +82892,7 @@ case OP_AggStep: {
       rc = pCtx->isError;
     }
     sqlite3VdbeMemRelease(&t);
+    if( rc ) goto abort_due_to_error;
   }else{
     assert( t.flags==MEM_Null );
   }
@@ -80377,12 +82919,13 @@ case OP_AggStep: {
 */
 case OP_AggFinal: {
   Mem *pMem;
-  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+  assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
   pMem = &aMem[pOp->p1];
   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
   rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
   if( rc ){
     sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
+    goto abort_due_to_error;
   }
   sqlite3VdbeChangeEncoding(pMem, encoding);
   UPDATE_MAX_BLOBSIZE(pMem);
@@ -80418,7 +82961,8 @@ case OP_Checkpoint: {
        || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
   );
   rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
-  if( rc==SQLITE_BUSY ){
+  if( rc ){
+    if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
     rc = SQLITE_OK;
     aRes[0] = 1;
   }
@@ -80491,7 +83035,7 @@ case OP_JournalMode: {    /* out2 */
           "cannot change %s wal mode from within a transaction",
           (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
       );
-      break;
+      goto abort_due_to_error;
     }else{
  
       if( eOld==PAGER_JOURNALMODE_WAL ){
@@ -80521,9 +83065,7 @@ case OP_JournalMode: {    /* out2 */
   }
 #endif /* ifndef SQLITE_OMIT_WAL */
 
-  if( rc ){
-    eNew = eOld;
-  }
+  if( rc ) eNew = eOld;
   eNew = sqlite3PagerSetJournalMode(pPager, eNew);
 
   pOut->flags = MEM_Str|MEM_Static|MEM_Term;
@@ -80531,6 +83073,7 @@ case OP_JournalMode: {    /* out2 */
   pOut->n = sqlite3Strlen30(pOut->z);
   pOut->enc = SQLITE_UTF8;
   sqlite3VdbeChangeEncoding(pOut, encoding);
+  if( rc ) goto abort_due_to_error;
   break;
 };
 #endif /* SQLITE_OMIT_PRAGMA */
@@ -80545,6 +83088,7 @@ case OP_JournalMode: {    /* out2 */
 case OP_Vacuum: {
   assert( p->readOnly==0 );
   rc = sqlite3RunVacuum(&p->zErrMsg, db);
+  if( rc ) goto abort_due_to_error;
   break;
 }
 #endif
@@ -80565,7 +83109,8 @@ case OP_IncrVacuum: {        /* jump */
   pBt = db->aDb[pOp->p1].pBt;
   rc = sqlite3BtreeIncrVacuum(pBt);
   VdbeBranchTaken(rc==SQLITE_DONE,2);
-  if( rc==SQLITE_DONE ){
+  if( rc ){
+    if( rc!=SQLITE_DONE ) goto abort_due_to_error;
     rc = SQLITE_OK;
     goto jump_to_p2;
   }
@@ -80616,9 +83161,12 @@ case OP_TableLock: {
     assert( DbMaskTest(p->btreeMask, p1) );
     assert( isWriteLock==0 || isWriteLock==1 );
     rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
-    if( (rc&0xFF)==SQLITE_LOCKED ){
-      const char *z = pOp->p4.z;
-      sqlite3VdbeError(p, "database table is locked: %s", z);
+    if( rc ){
+      if( (rc&0xFF)==SQLITE_LOCKED ){
+        const char *z = pOp->p4.z;
+        sqlite3VdbeError(p, "database table is locked: %s", z);
+      }
+      goto abort_due_to_error;
     }
   }
   break;
@@ -80640,6 +83188,7 @@ case OP_VBegin: {
   pVTab = pOp->p4.pVtab;
   rc = sqlite3VtabBegin(db, pVTab);
   if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
+  if( rc ) goto abort_due_to_error;
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -80668,6 +83217,7 @@ case OP_VCreate: {
     rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
   }
   sqlite3VdbeMemRelease(&sMem);
+  if( rc ) goto abort_due_to_error;
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -80682,6 +83232,7 @@ case OP_VDestroy: {
   db->nVDestroy++;
   rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
   db->nVDestroy--;
+  if( rc ) goto abort_due_to_error;
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -80705,25 +83256,25 @@ case OP_VOpen: {
   pVtab = pOp->p4.pVtab->pVtab;
   if( pVtab==0 || NEVER(pVtab->pModule==0) ){
     rc = SQLITE_LOCKED;
-    break;
+    goto abort_due_to_error;
   }
   pModule = pVtab->pModule;
   rc = pModule->xOpen(pVtab, &pVCur);
   sqlite3VtabImportErrmsg(p, pVtab);
-  if( SQLITE_OK==rc ){
-    /* Initialize sqlite3_vtab_cursor base class */
-    pVCur->pVtab = pVtab;
+  if( rc ) goto abort_due_to_error;
 
-    /* Initialize vdbe cursor object */
-    pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
-    if( pCur ){
-      pCur->uc.pVCur = pVCur;
-      pVtab->nRef++;
-    }else{
-      assert( db->mallocFailed );
-      pModule->xClose(pVCur);
-      goto no_mem;
-    }
+  /* Initialize sqlite3_vtab_cursor base class */
+  pVCur->pVtab = pVtab;
+
+  /* Initialize vdbe cursor object */
+  pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
+  if( pCur ){
+    pCur->uc.pVCur = pVCur;
+    pVtab->nRef++;
+  }else{
+    assert( db->mallocFailed );
+    pModule->xClose(pVCur);
+    goto no_mem;
   }
   break;
 }
@@ -80785,9 +83336,8 @@ case OP_VFilter: {   /* jump */
   }
   rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
   sqlite3VtabImportErrmsg(p, pVtab);
-  if( rc==SQLITE_OK ){
-    res = pModule->xEof(pVCur);
-  }
+  if( rc ) goto abort_due_to_error;
+  res = pModule->xEof(pVCur);
   pCur->nullRow = 0;
   VdbeBranchTaken(res!=0,2);
   if( res ) goto jump_to_p2;
@@ -80811,7 +83361,7 @@ case OP_VColumn: {
 
   VdbeCursor *pCur = p->apCsr[pOp->p1];
   assert( pCur->eCurType==CURTYPE_VTAB );
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
   pDest = &aMem[pOp->p3];
   memAboutToChange(p, pDest);
   if( pCur->nullRow ){
@@ -80836,6 +83386,7 @@ case OP_VColumn: {
   if( sqlite3VdbeMemTooBig(pDest) ){
     goto too_big;
   }
+  if( rc ) goto abort_due_to_error;
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -80871,9 +83422,8 @@ case OP_VNext: {   /* jump */
   */
   rc = pModule->xNext(pCur->uc.pVCur);
   sqlite3VtabImportErrmsg(p, pVtab);
-  if( rc==SQLITE_OK ){
-    res = pModule->xEof(pCur->uc.pVCur);
-  }
+  if( rc ) goto abort_due_to_error;
+  res = pModule->xEof(pCur->uc.pVCur);
   VdbeBranchTaken(!res,2);
   if( !res ){
     /* If there is data, jump to P2 */
@@ -80905,11 +83455,11 @@ case OP_VRename: {
   testcase( pName->enc==SQLITE_UTF16BE );
   testcase( pName->enc==SQLITE_UTF16LE );
   rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
-  if( rc==SQLITE_OK ){
-    rc = pVtab->pModule->xRename(pVtab, pName->z);
-    sqlite3VtabImportErrmsg(p, pVtab);
-    p->expired = 0;
-  }
+  if( rc ) goto abort_due_to_error;
+  rc = pVtab->pModule->xRename(pVtab, pName->z);
+  sqlite3VtabImportErrmsg(p, pVtab);
+  p->expired = 0;
+  if( rc ) goto abort_due_to_error;
   break;
 }
 #endif
@@ -80958,7 +83508,7 @@ case OP_VUpdate: {
   pVtab = pOp->p4.pVtab->pVtab;
   if( pVtab==0 || NEVER(pVtab->pModule==0) ){
     rc = SQLITE_LOCKED;
-    break;
+    goto abort_due_to_error;
   }
   pModule = pVtab->pModule;
   nArg = pOp->p2;
@@ -80990,6 +83540,7 @@ case OP_VUpdate: {
     }else{
       p->nChange++;
     }
+    if( rc ) goto abort_due_to_error;
   }
   break;
 }
@@ -81146,11 +83697,12 @@ default: {          /* This is really OP_Noop and OP_Explain */
 
 #ifdef SQLITE_DEBUG
     if( db->flags & SQLITE_VdbeTrace ){
+      u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode];
       if( rc!=0 ) printf("rc=%d\n",rc);
-      if( pOrigOp->opflags & (OPFLG_OUT2) ){
+      if( opProperty & (OPFLG_OUT2) ){
         registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
       }
-      if( pOrigOp->opflags & OPFLG_OUT3 ){
+      if( opProperty & OPFLG_OUT3 ){
         registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
       }
     }
@@ -81161,9 +83713,14 @@ default: {          /* This is really OP_Noop and OP_Explain */
   /* If we reach this point, it means that execution is finished with
   ** an error of some kind.
   */
-vdbe_error_halt:
+abort_due_to_error:
+  if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT;
   assert( rc );
+  if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
+    sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
+  }
   p->rc = rc;
+  sqlite3SystemError(db, rc);
   testcase( sqlite3GlobalConfig.xLog!=0 );
   sqlite3_log(rc, "statement aborts at %d: [%s] %s", 
                    (int)(pOp - aOp), p->zSql, p->zErrMsg);
@@ -81193,36 +83750,25 @@ vdbe_return:
 too_big:
   sqlite3VdbeError(p, "string or blob too big");
   rc = SQLITE_TOOBIG;
-  goto vdbe_error_halt;
+  goto abort_due_to_error;
 
   /* Jump to here if a malloc() fails.
   */
 no_mem:
   sqlite3OomFault(db);
   sqlite3VdbeError(p, "out of memory");
-  rc = SQLITE_NOMEM;
-  goto vdbe_error_halt;
-
-  /* Jump to here for any other kind of fatal error.  The "rc" variable
-  ** should hold the error number.
-  */
-abort_due_to_error:
-  assert( p->zErrMsg==0 );
-  if( db->mallocFailed ) rc = SQLITE_NOMEM;
-  if( rc!=SQLITE_IOERR_NOMEM ){
-    sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
-  }
-  goto vdbe_error_halt;
+  rc = SQLITE_NOMEM_BKPT;
+  goto abort_due_to_error;
 
   /* Jump to here if the sqlite3_interrupt() API sets the interrupt
   ** flag.
   */
 abort_due_to_interrupt:
   assert( db->u1.isInterrupted );
-  rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_INTERRUPT;
+  rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
   p->rc = rc;
   sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
-  goto vdbe_error_halt;
+  goto abort_due_to_error;
 }
 
 
@@ -81260,6 +83806,8 @@ struct Incrblob {
   BtCursor *pCsr;         /* Cursor pointing at blob row */
   sqlite3_stmt *pStmt;    /* Statement holding cursor open */
   sqlite3 *db;            /* The associated database */
+  char *zDb;              /* Database name */
+  Table *pTab;            /* Table object */
 };
 
 
@@ -81403,6 +83951,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
       sqlite3BtreeLeaveAll(db);
       goto blob_open_out;
     }
+    pBlob->pTab = pTab;
+    pBlob->zDb = (char *) db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zName;
 
     /* Now search pTab for the exact column. */
     for(iCol=0; iCol<pTab->nCol; iCol++) {
@@ -81624,6 +84174,30 @@ static int blobReadWrite(
     */
     assert( db == v->db );
     sqlite3BtreeEnterCursor(p->pCsr);
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+    if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){
+      /* If a pre-update hook is registered and this is a write cursor, 
+      ** invoke it here. 
+      ** 
+      ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this
+      ** operation should really be an SQLITE_UPDATE. This is probably
+      ** incorrect, but is convenient because at this point the new.* values 
+      ** are not easily obtainable. And for the sessions module, an 
+      ** SQLITE_UPDATE where the PK columns do not change is handled in the 
+      ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
+      ** slightly more efficient). Since you cannot write to a PK column
+      ** using the incremental-blob API, this works. For the sessions module
+      ** anyhow.
+      */
+      sqlite3_int64 iKey;
+      sqlite3BtreeKeySize(p->pCsr, &iKey);
+      sqlite3VdbePreUpdateHook(
+          v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1
+      );
+    }
+#endif
+
     rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
     sqlite3BtreeLeaveCursor(p->pCsr);
     if( rc==SQLITE_ABORT ){
@@ -82250,7 +84824,7 @@ static int vdbePmaReadBlob(
       int nNew = MAX(128, p->nAlloc*2);
       while( nByte>nNew ) nNew = nNew*2;
       aNew = sqlite3Realloc(p->aAlloc, nNew);
-      if( !aNew ) return SQLITE_NOMEM;
+      if( !aNew ) return SQLITE_NOMEM_BKPT;
       p->nAlloc = nNew;
       p->aAlloc = aNew;
     }
@@ -82362,7 +84936,7 @@ static int vdbePmaReaderSeek(
     int iBuf = pReadr->iReadOff % pgsz;
     if( pReadr->aBuffer==0 ){
       pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
-      if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM;
+      if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT;
       pReadr->nBuffer = pgsz;
     }
     if( rc==SQLITE_OK && iBuf ){
@@ -82641,7 +85215,6 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
 ){
   int pgsz;                       /* Page size of main database */
   int i;                          /* Used to iterate through aTask[] */
-  int mxCache;                    /* Cache size */
   VdbeSorter *pSorter;            /* The new sorter */
   KeyInfo *pKeyInfo;              /* Copy of pCsr->pKeyInfo with db==0 */
   int szKeyInfo;                  /* Size of pCsr->pKeyInfo in bytes */
@@ -82678,7 +85251,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
   pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
   pCsr->uc.pSorter = pSorter;
   if( pSorter==0 ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }else{
     pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
     memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
@@ -82698,11 +85271,20 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
     }
 
     if( !sqlite3TempInMemory(db) ){
+      i64 mxCache;                /* Cache size in bytes*/
       u32 szPma = sqlite3GlobalConfig.szPma;
       pSorter->mnPmaSize = szPma * pgsz;
+
       mxCache = db->aDb[0].pSchema->cache_size;
-      if( mxCache<(int)szPma ) mxCache = (int)szPma;
-      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
+      if( mxCache<0 ){
+        /* A negative cache-size value C indicates that the cache is abs(C)
+        ** KiB in size.  */
+        mxCache = mxCache * -1024;
+      }else{
+        mxCache = mxCache * pgsz;
+      }
+      mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
+      pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
 
       /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
       ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
@@ -82712,7 +85294,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
         assert( pSorter->iMemory==0 );
         pSorter->nMemory = pgsz;
         pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
-        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
+        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
       }
     }
 
@@ -83034,7 +85616,7 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
         pTask->pSorter->pKeyInfo, 0, 0, &pFree
     );
     assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
-    if( pFree==0 ) return SQLITE_NOMEM;
+    if( pFree==0 ) return SQLITE_NOMEM_BKPT;
     pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
     pTask->pUnpacked->errCode = 0;
   }
@@ -83109,7 +85691,7 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
 
   aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
   if( !aSlot ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 
   while( p ){
@@ -83159,7 +85741,7 @@ static void vdbePmaWriterInit(
   memset(p, 0, sizeof(PmaWriter));
   p->aBuffer = (u8*)sqlite3Malloc(nBuf);
   if( !p->aBuffer ){
-    p->eFWErr = SQLITE_NOMEM;
+    p->eFWErr = SQLITE_NOMEM_BKPT;
   }else{
     p->iBufEnd = p->iBufStart = (iStart % nBuf);
     p->iWriteOff = iStart - p->iBufStart;
@@ -83447,7 +86029,7 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
         pSorter->nMemory = sqlite3MallocSize(aMem);
       }else if( pSorter->list.aMemory ){
         pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
-        if( !pSorter->list.aMemory ) return SQLITE_NOMEM;
+        if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT;
       }
 
       rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
@@ -83538,7 +86120,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
       if( nNew < nMin ) nNew = nMin;
 
       aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
-      if( !aNew ) return SQLITE_NOMEM;
+      if( !aNew ) return SQLITE_NOMEM_BKPT;
       pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
       pSorter->list.aMemory = aNew;
       pSorter->nMemory = nNew;
@@ -83552,7 +86134,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
   }else{
     pNew = (SorterRecord *)sqlite3Malloc(nReq);
     if( pNew==0 ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     pNew->u.pNext = pSorter->list.pList;
   }
@@ -83699,7 +86281,7 @@ static int vdbeIncrMergerNew(
     pTask->file2.iEof += pIncr->mxSz;
   }else{
     vdbeMergeEngineFree(pMerger);
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }
   return rc;
 }
@@ -84004,10 +86586,10 @@ static int vdbeMergeEngineLevel0(
   int rc = SQLITE_OK;
 
   *ppOut = pNew = vdbeMergeEngineNew(nPMA);
-  if( pNew==0 ) rc = SQLITE_NOMEM;
+  if( pNew==0 ) rc = SQLITE_NOMEM_BKPT;
 
   for(i=0; i<nPMA && rc==SQLITE_OK; i++){
-    i64 nDummy;
+    i64 nDummy = 0;
     PmaReader *pReadr = &pNew->aReadr[i];
     rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
     iOff = pReadr->iEof;
@@ -84075,7 +86657,7 @@ static int vdbeSorterAddToTree(
     if( pReadr->pIncr==0 ){
       MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
       if( pNew==0 ){
-        rc = SQLITE_NOMEM;
+        rc = SQLITE_NOMEM_BKPT;
       }else{
         rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
       }
@@ -84120,7 +86702,7 @@ static int vdbeSorterMergeTreeBuild(
   assert( pSorter->bUseThreads || pSorter->nTask==1 );
   if( pSorter->nTask>1 ){
     pMain = vdbeMergeEngineNew(pSorter->nTask);
-    if( pMain==0 ) rc = SQLITE_NOMEM;
+    if( pMain==0 ) rc = SQLITE_NOMEM_BKPT;
   }
 #endif
 
@@ -84138,7 +86720,7 @@ static int vdbeSorterMergeTreeBuild(
         int i;
         int iSeq = 0;
         pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
-        if( pRoot==0 ) rc = SQLITE_NOMEM;
+        if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT;
         for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
           MergeEngine *pMerger = 0; /* New level-0 PMA merger */
           int nReader;              /* Number of level-0 PMAs to merge */
@@ -84209,7 +86791,7 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
       if( rc==SQLITE_OK ){
         pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
         pSorter->pReader = pReadr;
-        if( pReadr==0 ) rc = SQLITE_NOMEM;
+        if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT;
       }
       if( rc==SQLITE_OK ){
         rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
@@ -84386,7 +86968,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
   pSorter = pCsr->uc.pSorter;
   pKey = vdbeSorterRowkey(pSorter, &nKey);
   if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   pOut->n = nKey;
   MemSetTypeFlag(pOut, MEM_Blob);
@@ -84431,7 +87013,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
     char *p;
     r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
     assert( pSorter->pUnpacked==(UnpackedRecord*)p );
-    if( r2==0 ) return SQLITE_NOMEM;
+    if( r2==0 ) return SQLITE_NOMEM_BKPT;
     r2->nField = nKeyCol;
   }
   assert( r2->nField==nKeyCol );
@@ -84450,265 +87032,6 @@ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
 }
 
 /************** End of vdbesort.c ********************************************/
-/************** Begin file journal.c *****************************************/
-/*
-** 2007 August 22
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file implements a special kind of sqlite3_file object used
-** by SQLite to create journal files if the atomic-write optimization
-** is enabled.
-**
-** The distinctive characteristic of this sqlite3_file is that the
-** actual on disk file is created lazily. When the file is created,
-** the caller specifies a buffer size for an in-memory buffer to
-** be used to service read() and write() requests. The actual file
-** on disk is not created or populated until either:
-**
-**   1) The in-memory representation grows too large for the allocated 
-**      buffer, or
-**   2) The sqlite3JournalCreate() function is called.
-*/
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-/* #include "sqliteInt.h" */
-
-
-/*
-** A JournalFile object is a subclass of sqlite3_file used by
-** as an open file handle for journal files.
-*/
-struct JournalFile {
-  sqlite3_io_methods *pMethod;    /* I/O methods on journal files */
-  int nBuf;                       /* Size of zBuf[] in bytes */
-  char *zBuf;                     /* Space to buffer journal writes */
-  int iSize;                      /* Amount of zBuf[] currently used */
-  int flags;                      /* xOpen flags */
-  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
-  sqlite3_file *pReal;            /* The "real" underlying file descriptor */
-  const char *zJournal;           /* Name of the journal file */
-};
-typedef struct JournalFile JournalFile;
-
-/*
-** If it does not already exists, create and populate the on-disk file 
-** for JournalFile p.
-*/
-static int createFile(JournalFile *p){
-  int rc = SQLITE_OK;
-  if( !p->pReal ){
-    sqlite3_file *pReal = (sqlite3_file *)&p[1];
-    rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
-    if( rc==SQLITE_OK ){
-      p->pReal = pReal;
-      if( p->iSize>0 ){
-        assert(p->iSize<=p->nBuf);
-        rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
-      }
-      if( rc!=SQLITE_OK ){
-        /* If an error occurred while writing to the file, close it before
-        ** returning. This way, SQLite uses the in-memory journal data to 
-        ** roll back changes made to the internal page-cache before this
-        ** function was called.  */
-        sqlite3OsClose(pReal);
-        p->pReal = 0;
-      }
-    }
-  }
-  return rc;
-}
-
-/*
-** Close the file.
-*/
-static int jrnlClose(sqlite3_file *pJfd){
-  JournalFile *p = (JournalFile *)pJfd;
-  if( p->pReal ){
-    sqlite3OsClose(p->pReal);
-  }
-  sqlite3_free(p->zBuf);
-  return SQLITE_OK;
-}
-
-/*
-** Read data from the file.
-*/
-static int jrnlRead(
-  sqlite3_file *pJfd,    /* The journal file from which to read */
-  void *zBuf,            /* Put the results here */
-  int iAmt,              /* Number of bytes to read */
-  sqlite_int64 iOfst     /* Begin reading at this offset */
-){
-  int rc = SQLITE_OK;
-  JournalFile *p = (JournalFile *)pJfd;
-  if( p->pReal ){
-    rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
-  }else if( (iAmt+iOfst)>p->iSize ){
-    rc = SQLITE_IOERR_SHORT_READ;
-  }else{
-    memcpy(zBuf, &p->zBuf[iOfst], iAmt);
-  }
-  return rc;
-}
-
-/*
-** Write data to the file.
-*/
-static int jrnlWrite(
-  sqlite3_file *pJfd,    /* The journal file into which to write */
-  const void *zBuf,      /* Take data to be written from here */
-  int iAmt,              /* Number of bytes to write */
-  sqlite_int64 iOfst     /* Begin writing at this offset into the file */
-){
-  int rc = SQLITE_OK;
-  JournalFile *p = (JournalFile *)pJfd;
-  if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
-    rc = createFile(p);
-  }
-  if( rc==SQLITE_OK ){
-    if( p->pReal ){
-      rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
-    }else{
-      memcpy(&p->zBuf[iOfst], zBuf, iAmt);
-      if( p->iSize<(iOfst+iAmt) ){
-        p->iSize = (iOfst+iAmt);
-      }
-    }
-  }
-  return rc;
-}
-
-/*
-** Truncate the file.
-*/
-static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
-  int rc = SQLITE_OK;
-  JournalFile *p = (JournalFile *)pJfd;
-  if( p->pReal ){
-    rc = sqlite3OsTruncate(p->pReal, size);
-  }else if( size<p->iSize ){
-    p->iSize = size;
-  }
-  return rc;
-}
-
-/*
-** Sync the file.
-*/
-static int jrnlSync(sqlite3_file *pJfd, int flags){
-  int rc;
-  JournalFile *p = (JournalFile *)pJfd;
-  if( p->pReal ){
-    rc = sqlite3OsSync(p->pReal, flags);
-  }else{
-    rc = SQLITE_OK;
-  }
-  return rc;
-}
-
-/*
-** Query the size of the file in bytes.
-*/
-static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
-  int rc = SQLITE_OK;
-  JournalFile *p = (JournalFile *)pJfd;
-  if( p->pReal ){
-    rc = sqlite3OsFileSize(p->pReal, pSize);
-  }else{
-    *pSize = (sqlite_int64) p->iSize;
-  }
-  return rc;
-}
-
-/*
-** Table of methods for JournalFile sqlite3_file object.
-*/
-static struct sqlite3_io_methods JournalFileMethods = {
-  1,             /* iVersion */
-  jrnlClose,     /* xClose */
-  jrnlRead,      /* xRead */
-  jrnlWrite,     /* xWrite */
-  jrnlTruncate,  /* xTruncate */
-  jrnlSync,      /* xSync */
-  jrnlFileSize,  /* xFileSize */
-  0,             /* xLock */
-  0,             /* xUnlock */
-  0,             /* xCheckReservedLock */
-  0,             /* xFileControl */
-  0,             /* xSectorSize */
-  0,             /* xDeviceCharacteristics */
-  0,             /* xShmMap */
-  0,             /* xShmLock */
-  0,             /* xShmBarrier */
-  0              /* xShmUnmap */
-};
-
-/* 
-** Open a journal file.
-*/
-SQLITE_PRIVATE int sqlite3JournalOpen(
-  sqlite3_vfs *pVfs,         /* The VFS to use for actual file I/O */
-  const char *zName,         /* Name of the journal file */
-  sqlite3_file *pJfd,        /* Preallocated, blank file handle */
-  int flags,                 /* Opening flags */
-  int nBuf                   /* Bytes buffered before opening the file */
-){
-  JournalFile *p = (JournalFile *)pJfd;
-  memset(p, 0, sqlite3JournalSize(pVfs));
-  if( nBuf>0 ){
-    p->zBuf = sqlite3MallocZero(nBuf);
-    if( !p->zBuf ){
-      return SQLITE_NOMEM;
-    }
-  }else{
-    return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
-  }
-  p->pMethod = &JournalFileMethods;
-  p->nBuf = nBuf;
-  p->flags = flags;
-  p->zJournal = zName;
-  p->pVfs = pVfs;
-  return SQLITE_OK;
-}
-
-/*
-** If the argument p points to a JournalFile structure, and the underlying
-** file has not yet been created, create it now.
-*/
-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
-  if( p->pMethods!=&JournalFileMethods ){
-    return SQLITE_OK;
-  }
-  return createFile((JournalFile *)p);
-}
-
-/*
-** The file-handle passed as the only argument is guaranteed to be an open
-** file. It may or may not be of class JournalFile. If the file is a
-** JournalFile, and the underlying file on disk has not yet been opened,
-** return 0. Otherwise, return 1.
-*/
-SQLITE_PRIVATE int sqlite3JournalExists(sqlite3_file *p){
-  return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0);
-}
-
-/* 
-** Return the number of bytes required to store a JournalFile that uses vfs
-** pVfs to create the underlying on-disk files.
-*/
-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
-  return (pVfs->szOsFile+sizeof(JournalFile));
-}
-#endif
-
-/************** End of journal.c *********************************************/
 /************** Begin file memjournal.c **************************************/
 /*
 ** 2008 October 7
@@ -84725,6 +87048,15 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
 ** This file contains code use to implement an in-memory rollback journal.
 ** The in-memory rollback journal is used to journal transactions for
 ** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
+**
+** Update:  The in-memory journal is also used to temporarily cache
+** smaller journals that are not critical for power-loss recovery.
+** For example, statement journals that are not too big will be held
+** entirely in memory, thus reducing the number of file I/O calls, and
+** more importantly, reducing temporary file creation events.  If these
+** journals become too large for memory, they are spilled to disk.  But
+** in the common case, they are usually small and no file I/O needs to
+** occur.
 */
 /* #include "sqliteInt.h" */
 
@@ -84733,25 +87065,29 @@ typedef struct MemJournal MemJournal;
 typedef struct FilePoint FilePoint;
 typedef struct FileChunk FileChunk;
 
-/* Space to hold the rollback journal is allocated in increments of
-** this many bytes.
-**
-** The size chosen is a little less than a power of two.  That way,
-** the FileChunk object will have a size that almost exactly fills
-** a power-of-two allocation.  This minimizes wasted space in power-of-two
-** memory allocators.
-*/
-#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
-
 /*
 ** The rollback journal is composed of a linked list of these structures.
+**
+** The zChunk array is always at least 8 bytes in size - usually much more.
+** Its actual size is stored in the MemJournal.nChunkSize variable.
 */
 struct FileChunk {
   FileChunk *pNext;               /* Next chunk in the journal */
-  u8 zChunk[JOURNAL_CHUNKSIZE];   /* Content of this chunk */
+  u8 zChunk[8];                   /* Content of this chunk */
 };
 
 /*
+** By default, allocate this many bytes of memory for each FileChunk object.
+*/
+#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024
+
+/*
+** For chunk size nChunkSize, return the number of bytes that should
+** be allocated for each FileChunk structure.
+*/
+#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8))
+
+/*
 ** An instance of this object serves as a cursor into the rollback journal.
 ** The cursor can be either for reading or writing.
 */
@@ -84761,14 +87097,22 @@ struct FilePoint {
 };
 
 /*
-** This subclass is a subclass of sqlite3_file.  Each open memory-journal
+** This structure is a subclass of sqlite3_file. Each open memory-journal
 ** is an instance of this class.
 */
 struct MemJournal {
-  sqlite3_io_methods *pMethod;    /* Parent class. MUST BE FIRST */
+  const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
+  int nChunkSize;                 /* In-memory chunk-size */
+
+  int nSpill;                     /* Bytes of data before flushing */
+  int nSize;                      /* Bytes of data currently in memory */
   FileChunk *pFirst;              /* Head of in-memory chunk-list */
   FilePoint endpoint;             /* Pointer to the end of the file */
   FilePoint readpoint;            /* Pointer to the end of the last xRead() */
+
+  int flags;                      /* xOpen flags */
+  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
+  const char *zJournal;           /* Name of the journal file */
 };
 
 /*
@@ -84787,37 +87131,95 @@ static int memjrnlRead(
   int iChunkOffset;
   FileChunk *pChunk;
 
-  /* SQLite never tries to read past the end of a rollback journal file */
-  assert( iOfst+iAmt<=p->endpoint.iOffset );
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+  if( (iAmt+iOfst)>p->endpoint.iOffset ){
+    return SQLITE_IOERR_SHORT_READ;
+  }
+#endif
 
+  assert( (iAmt+iOfst)<=p->endpoint.iOffset );
+  assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
   if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
     sqlite3_int64 iOff = 0;
     for(pChunk=p->pFirst; 
-        ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst;
+        ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
         pChunk=pChunk->pNext
     ){
-      iOff += JOURNAL_CHUNKSIZE;
+      iOff += p->nChunkSize;
     }
   }else{
     pChunk = p->readpoint.pChunk;
+    assert( pChunk!=0 );
   }
 
-  iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
+  iChunkOffset = (int)(iOfst%p->nChunkSize);
   do {
-    int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
-    int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
-    memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
+    int iSpace = p->nChunkSize - iChunkOffset;
+    int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset));
+    memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy);
     zOut += nCopy;
     nRead -= iSpace;
     iChunkOffset = 0;
   } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
-  p->readpoint.iOffset = iOfst+iAmt;
+  p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0;
   p->readpoint.pChunk = pChunk;
 
   return SQLITE_OK;
 }
 
 /*
+** Free the list of FileChunk structures headed at MemJournal.pFirst.
+*/
+static void memjrnlFreeChunks(MemJournal *p){
+  FileChunk *pIter;
+  FileChunk *pNext;
+  for(pIter=p->pFirst; pIter; pIter=pNext){
+    pNext = pIter->pNext;
+    sqlite3_free(pIter);
+  } 
+  p->pFirst = 0;
+}
+
+/*
+** Flush the contents of memory to a real file on disk.
+*/
+static int memjrnlCreateFile(MemJournal *p){
+  int rc;
+  sqlite3_file *pReal = (sqlite3_file*)p;
+  MemJournal copy = *p;
+
+  memset(p, 0, sizeof(MemJournal));
+  rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0);
+  if( rc==SQLITE_OK ){
+    int nChunk = copy.nChunkSize;
+    i64 iOff = 0;
+    FileChunk *pIter;
+    for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){
+      if( iOff + nChunk > copy.endpoint.iOffset ){
+        nChunk = copy.endpoint.iOffset - iOff;
+      }
+      rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff);
+      if( rc ) break;
+      iOff += nChunk;
+    }
+    if( rc==SQLITE_OK ){
+      /* No error has occurred. Free the in-memory buffers. */
+      memjrnlFreeChunks(&copy);
+    }
+  }
+  if( rc!=SQLITE_OK ){
+    /* If an error occurred while creating or writing to the file, restore
+    ** the original before returning. This way, SQLite uses the in-memory
+    ** journal data to roll back changes made to the internal page-cache
+    ** before this function was called.  */
+    sqlite3OsClose(pReal);
+    *p = copy;
+  }
+  return rc;
+}
+
+
+/*
 ** Write data to the file.
 */
 static int memjrnlWrite(
@@ -84830,38 +87232,62 @@ static int memjrnlWrite(
   int nWrite = iAmt;
   u8 *zWrite = (u8 *)zBuf;
 
-  /* An in-memory journal file should only ever be appended to. Random
-  ** access writes are not required by sqlite.
-  */
-  assert( iOfst==p->endpoint.iOffset );
-  UNUSED_PARAMETER(iOfst);
+  /* If the file should be created now, create it and write the new data
+  ** into the file on disk. */
+  if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
+    int rc = memjrnlCreateFile(p);
+    if( rc==SQLITE_OK ){
+      rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst);
+    }
+    return rc;
+  }
 
-  while( nWrite>0 ){
-    FileChunk *pChunk = p->endpoint.pChunk;
-    int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
-    int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
+  /* If the contents of this write should be stored in memory */
+  else{
+    /* An in-memory journal file should only ever be appended to. Random
+    ** access writes are not required. The only exception to this is when
+    ** the in-memory journal is being used by a connection using the
+    ** atomic-write optimization. In this case the first 28 bytes of the
+    ** journal file may be written as part of committing the transaction. */ 
+    assert( iOfst==p->endpoint.iOffset || iOfst==0 );
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+    if( iOfst==0 && p->pFirst ){
+      assert( p->nChunkSize>iAmt );
+      memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
+    }else
+#else
+    assert( iOfst>0 || p->pFirst==0 );
+#endif
+    {
+      while( nWrite>0 ){
+        FileChunk *pChunk = p->endpoint.pChunk;
+        int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
+        int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
+
+        if( iChunkOffset==0 ){
+          /* New chunk is required to extend the file. */
+          FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
+          if( !pNew ){
+            return SQLITE_IOERR_NOMEM_BKPT;
+          }
+          pNew->pNext = 0;
+          if( pChunk ){
+            assert( p->pFirst );
+            pChunk->pNext = pNew;
+          }else{
+            assert( !p->pFirst );
+            p->pFirst = pNew;
+          }
+          p->endpoint.pChunk = pNew;
+        }
 
-    if( iChunkOffset==0 ){
-      /* New chunk is required to extend the file. */
-      FileChunk *pNew = sqlite3Malloc(sizeof(FileChunk));
-      if( !pNew ){
-        return SQLITE_IOERR_NOMEM;
-      }
-      pNew->pNext = 0;
-      if( pChunk ){
-        assert( p->pFirst );
-        pChunk->pNext = pNew;
-      }else{
-        assert( !p->pFirst );
-        p->pFirst = pNew;
+        memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
+        zWrite += iSpace;
+        nWrite -= iSpace;
+        p->endpoint.iOffset += iSpace;
       }
-      p->endpoint.pChunk = pNew;
+      p->nSize = iAmt + iOfst;
     }
-
-    memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
-    zWrite += iSpace;
-    nWrite -= iSpace;
-    p->endpoint.iOffset += iSpace;
   }
 
   return SQLITE_OK;
@@ -84869,19 +87295,21 @@ static int memjrnlWrite(
 
 /*
 ** Truncate the file.
+**
+** If the journal file is already on disk, truncate it there. Or, if it
+** is still in main memory but is being truncated to zero bytes in size,
+** ignore 
 */
 static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
   MemJournal *p = (MemJournal *)pJfd;
-  FileChunk *pChunk;
-  assert(size==0);
-  UNUSED_PARAMETER(size);
-  pChunk = p->pFirst;
-  while( pChunk ){
-    FileChunk *pTmp = pChunk;
-    pChunk = pChunk->pNext;
-    sqlite3_free(pTmp);
-  }
-  sqlite3MemJournalOpen(pJfd);
+  if( ALWAYS(size==0) ){
+    memjrnlFreeChunks(p);
+    p->nSize = 0;
+    p->endpoint.pChunk = 0;
+    p->endpoint.iOffset = 0;
+    p->readpoint.pChunk = 0;
+    p->readpoint.iOffset = 0;
+  }
   return SQLITE_OK;
 }
 
@@ -84889,21 +87317,19 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
 ** Close the file.
 */
 static int memjrnlClose(sqlite3_file *pJfd){
-  memjrnlTruncate(pJfd, 0);
+  MemJournal *p = (MemJournal *)pJfd;
+  memjrnlFreeChunks(p);
   return SQLITE_OK;
 }
 
-
 /*
 ** Sync the file.
 **
-** Syncing an in-memory journal is a no-op.  And, in fact, this routine
-** is never called in a working implementation.  This implementation
-** exists purely as a contingency, in case some malfunction in some other
-** part of SQLite causes Sync to be called by mistake.
+** If the real file has been created, call its xSync method. Otherwise, 
+** syncing an in-memory journal is a no-op. 
 */
-static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){
-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+static int memjrnlSync(sqlite3_file *pJfd, int flags){
+  UNUSED_PARAMETER2(pJfd, flags);
   return SQLITE_OK;
 }
 
@@ -84942,28 +87368,88 @@ static const struct sqlite3_io_methods MemJournalMethods = {
 };
 
 /* 
-** Open a journal file.
+** Open a journal file. 
+**
+** The behaviour of the journal file depends on the value of parameter 
+** nSpill. If nSpill is 0, then the journal file is always create and 
+** accessed using the underlying VFS. If nSpill is less than zero, then
+** all content is always stored in main-memory. Finally, if nSpill is a
+** positive value, then the journal file is initially created in-memory
+** but may be flushed to disk later on. In this case the journal file is
+** flushed to disk either when it grows larger than nSpill bytes in size,
+** or when sqlite3JournalCreate() is called.
+*/
+SQLITE_PRIVATE int sqlite3JournalOpen(
+  sqlite3_vfs *pVfs,         /* The VFS to use for actual file I/O */
+  const char *zName,         /* Name of the journal file */
+  sqlite3_file *pJfd,        /* Preallocated, blank file handle */
+  int flags,                 /* Opening flags */
+  int nSpill                 /* Bytes buffered before opening the file */
+){
+  MemJournal *p = (MemJournal*)pJfd;
+
+  /* Zero the file-handle object. If nSpill was passed zero, initialize
+  ** it using the sqlite3OsOpen() function of the underlying VFS. In this
+  ** case none of the code in this module is executed as a result of calls
+  ** made on the journal file-handle.  */
+  memset(p, 0, sizeof(MemJournal));
+  if( nSpill==0 ){
+    return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
+  }
+
+  if( nSpill>0 ){
+    p->nChunkSize = nSpill;
+  }else{
+    p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk);
+    assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) );
+  }
+
+  p->pMethod = (const sqlite3_io_methods*)&MemJournalMethods;
+  p->nSpill = nSpill;
+  p->flags = flags;
+  p->zJournal = zName;
+  p->pVfs = pVfs;
+  return SQLITE_OK;
+}
+
+/*
+** Open an in-memory journal file.
 */
 SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){
-  MemJournal *p = (MemJournal *)pJfd;
-  assert( EIGHT_BYTE_ALIGNMENT(p) );
-  memset(p, 0, sqlite3MemJournalSize());
-  p->pMethod = (sqlite3_io_methods*)&MemJournalMethods;
+  sqlite3JournalOpen(0, 0, pJfd, 0, -1);
+}
+
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+/*
+** If the argument p points to a MemJournal structure that is not an 
+** in-memory-only journal file (i.e. is one that was opened with a +ve
+** nSpill parameter), and the underlying file has not yet been created, 
+** create it now.
+*/
+SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
+  int rc = SQLITE_OK;
+  if( p->pMethods==&MemJournalMethods && ((MemJournal*)p)->nSpill>0 ){
+    rc = memjrnlCreateFile((MemJournal*)p);
+  }
+  return rc;
 }
+#endif
 
 /*
-** Return true if the file-handle passed as an argument is 
-** an in-memory journal 
+** The file-handle passed as the only argument is open on a journal file.
+** Return true if this "journal file" is currently stored in heap memory,
+** or false otherwise.
 */
-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *pJfd){
-  return pJfd->pMethods==&MemJournalMethods;
+SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){
+  return p->pMethods==&MemJournalMethods;
 }
 
 /* 
-** Return the number of bytes required to store a MemJournal file descriptor.
+** Return the number of bytes required to store a JournalFile that uses vfs
+** pVfs to create the underlying on-disk files.
 */
-SQLITE_PRIVATE int sqlite3MemJournalSize(void){
-  return sizeof(MemJournal);
+SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
+  return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
 }
 
 /************** End of memjournal.c ******************************************/
@@ -85790,9 +88276,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       notValid(pParse, pNC, "functions", NC_PartIdx);
       zId = pExpr->u.zToken;
       nId = sqlite3Strlen30(zId);
-      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
+      pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
       if( pDef==0 ){
-        pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
+        pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
         if( pDef==0 ){
           no_such_func = 1;
         }else{
@@ -85897,6 +88383,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
         assert( pNC->nRef>=nRef );
         if( nRef!=pNC->nRef ){
           ExprSetProperty(pExpr, EP_VarSelect);
+          pNC->ncFlags |= NC_VarSelect;
         }
       }
       break;
@@ -87104,15 +89591,13 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
         pNew->flags |= EP_IntValue;
         pNew->u.iValue = iValue;
       }else{
-        int c;
         pNew->u.zToken = (char*)&pNew[1];
         assert( pToken->z!=0 || pToken->n==0 );
         if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
         pNew->u.zToken[pToken->n] = 0;
-        if( dequote && nExtra>=3 
-             && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
+        if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
+          if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
           sqlite3Dequote(pNew->u.zToken);
-          if( c=='"' ) pNew->flags |= EP_DblQuoted;
         }
       }
     }
@@ -87196,6 +89681,22 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
 }
 
 /*
+** Add pSelect to the Expr.x.pSelect field.  Or, if pExpr is NULL (due
+** do a memory allocation failure) then delete the pSelect object.
+*/
+SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
+  if( pExpr ){
+    pExpr->x.pSelect = pSelect;
+    ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
+    sqlite3ExprSetHeightAndFlags(pParse, pExpr);
+  }else{
+    assert( pParse->db->mallocFailed );
+    sqlite3SelectDelete(pParse->db, pSelect);
+  }
+}
+
+
+/*
 ** If the expression is always either TRUE or FALSE (respectively),
 ** then return 1.  If one cannot determine the truth value of the
 ** expression at compile-time return 0.
@@ -87355,8 +89856,8 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
 /*
 ** Recursively delete an expression tree.
 */
-SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
-  if( p==0 ) return;
+static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
+  assert( p!=0 );
   /* Sanity check: Assert that the IntValue is non-negative if it exists */
   assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
   if( !ExprHasProperty(p, EP_TokenOnly) ){
@@ -87375,13 +89876,16 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
     sqlite3DbFree(db, p);
   }
 }
+SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
+  if( p ) sqlite3ExprDeleteNN(db, p);
+}
 
 /*
 ** Return the number of bytes allocated for the expression structure 
 ** passed as the first argument. This is always one of EXPR_FULLSIZE,
 ** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
 */
-static size_t exprStructSize(Expr *p){
+static int exprStructSize(Expr *p){
   if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
   if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
   return EXPR_FULLSIZE;
@@ -87426,7 +89930,7 @@ static int dupedExprStructSize(Expr *p, int flags){
   assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
   assert( EXPR_FULLSIZE<=0xfff );
   assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
-  if( 0==(flags&EXPRDUP_REDUCE) ){
+  if( 0==flags ){
     nSize = EXPR_FULLSIZE;
   }else{
     assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -87488,88 +89992,88 @@ static int dupedExprSize(Expr *p, int flags){
 ** if any. Before returning, *pzBuffer is set to the first byte past the
 ** portion of the buffer copied into by this function.
 */
-static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
-  Expr *pNew = 0;                      /* Value to return */
-  assert( flags==0 || flags==EXPRDUP_REDUCE );
+static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
+  Expr *pNew;           /* Value to return */
+  u8 *zAlloc;           /* Memory space from which to build Expr object */
+  u32 staticFlag;       /* EP_Static if space not obtained from malloc */
+
   assert( db!=0 );
-  if( p ){
-    const int isReduced = (flags&EXPRDUP_REDUCE);
-    u8 *zAlloc;
-    u32 staticFlag = 0;
+  assert( p );
+  assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
+  assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
 
-    assert( pzBuffer==0 || isReduced );
+  /* Figure out where to write the new Expr structure. */
+  if( pzBuffer ){
+    zAlloc = *pzBuffer;
+    staticFlag = EP_Static;
+  }else{
+    zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
+    staticFlag = 0;
+  }
+  pNew = (Expr *)zAlloc;
 
-    /* Figure out where to write the new Expr structure. */
-    if( pzBuffer ){
-      zAlloc = *pzBuffer;
-      staticFlag = EP_Static;
+  if( pNew ){
+    /* Set nNewSize to the size allocated for the structure pointed to
+    ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
+    ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
+    ** by the copy of the p->u.zToken string (if any).
+    */
+    const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
+    const int nNewSize = nStructSize & 0xfff;
+    int nToken;
+    if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+      nToken = sqlite3Strlen30(p->u.zToken) + 1;
     }else{
-      zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, flags));
+      nToken = 0;
     }
-    pNew = (Expr *)zAlloc;
-
-    if( pNew ){
-      /* Set nNewSize to the size allocated for the structure pointed to
-      ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
-      ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
-      ** by the copy of the p->u.zToken string (if any).
-      */
-      const unsigned nStructSize = dupedExprStructSize(p, flags);
-      const int nNewSize = nStructSize & 0xfff;
-      int nToken;
-      if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
-        nToken = sqlite3Strlen30(p->u.zToken) + 1;
-      }else{
-        nToken = 0;
-      }
-      if( isReduced ){
-        assert( ExprHasProperty(p, EP_Reduced)==0 );
-        memcpy(zAlloc, p, nNewSize);
-      }else{
-        size_t nSize = exprStructSize(p);
-        memcpy(zAlloc, p, nSize);
-        if( nSize<EXPR_FULLSIZE ){ 
-          memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
-        }
+    if( dupFlags ){
+      assert( ExprHasProperty(p, EP_Reduced)==0 );
+      memcpy(zAlloc, p, nNewSize);
+    }else{
+      u32 nSize = (u32)exprStructSize(p);
+      memcpy(zAlloc, p, nSize);
+      if( nSize<EXPR_FULLSIZE ){ 
+        memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
       }
+    }
 
-      /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
-      pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
-      pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
-      pNew->flags |= staticFlag;
-
-      /* Copy the p->u.zToken string, if any. */
-      if( nToken ){
-        char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
-        memcpy(zToken, p->u.zToken, nToken);
-      }
+    /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
+    pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
+    pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
+    pNew->flags |= staticFlag;
 
-      if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
-        /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
-        if( ExprHasProperty(p, EP_xIsSelect) ){
-          pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
-        }else{
-          pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
-        }
-      }
+    /* Copy the p->u.zToken string, if any. */
+    if( nToken ){
+      char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
+      memcpy(zToken, p->u.zToken, nToken);
+    }
 
-      /* Fill in pNew->pLeft and pNew->pRight. */
-      if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
-        zAlloc += dupedExprNodeSize(p, flags);
-        if( ExprHasProperty(pNew, EP_Reduced) ){
-          pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
-          pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
-        }
-        if( pzBuffer ){
-          *pzBuffer = zAlloc;
-        }
+    if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
+      /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
+      if( ExprHasProperty(p, EP_xIsSelect) ){
+        pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
       }else{
-        if( !ExprHasProperty(p, EP_TokenOnly) ){
-          pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
-          pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
-        }
+        pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
       }
+    }
 
+    /* Fill in pNew->pLeft and pNew->pRight. */
+    if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
+      zAlloc += dupedExprNodeSize(p, dupFlags);
+      if( ExprHasProperty(pNew, EP_Reduced) ){
+        pNew->pLeft = p->pLeft ?
+                      exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
+        pNew->pRight = p->pRight ?
+                       exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
+      }
+      if( pzBuffer ){
+        *pzBuffer = zAlloc;
+      }
+    }else{
+      if( !ExprHasProperty(p, EP_TokenOnly) ){
+        pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
+        pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+      }
     }
   }
   return pNew;
@@ -87621,7 +90125,7 @@ static With *withDup(sqlite3 *db, With *p){
 */
 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
   assert( flags==0 || flags==EXPRDUP_REDUCE );
-  return exprDup(db, p, flags, 0);
+  return p ? exprDup(db, p, flags, 0) : 0;
 }
 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
   ExprList *pNew;
@@ -87843,7 +90347,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(
     pItem = &pList->a[pList->nExpr-1];
     assert( pItem->zName==0 );
     pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
-    if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
+    if( dequote ) sqlite3Dequote(pItem->zName);
   }
 }
 
@@ -87892,10 +90396,9 @@ SQLITE_PRIVATE void sqlite3ExprListCheckLength(
 /*
 ** Delete an entire expression list.
 */
-SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
+static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
   int i;
   struct ExprList_item *pItem;
-  if( pList==0 ) return;
   assert( pList->a!=0 || pList->nExpr==0 );
   for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
     sqlite3ExprDelete(db, pItem->pExpr);
@@ -87905,6 +90408,9 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
   sqlite3DbFree(db, pList->a);
   sqlite3DbFree(db, pList);
 }
+SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
+  if( pList ) exprListDeleteNN(db, pList);
+}
 
 /*
 ** Return the bitwise-OR of all Expr.flags fields in the given
@@ -87916,7 +90422,8 @@ SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
   if( pList ){
     for(i=0; i<pList->nExpr; i++){
        Expr *pExpr = pList->a[i].pExpr;
-       if( ALWAYS(pExpr) ) m |= pExpr->flags;
+       assert( pExpr!=0 );
+       m |= pExpr->flags;
     }
   }
   return m;
@@ -88201,23 +90708,22 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){
 }
 
 /*
-** Return true if we are able to the IN operator optimization on a
-** query of the form
-**
-**       x IN (SELECT ...)
-**
-** Where the SELECT... clause is as specified by the parameter to this
-** routine.
-**
-** The Select object passed in has already been preprocessed and no
-** errors have been found.
+** pX is the RHS of an IN operator.  If pX is a SELECT statement 
+** that can be simplified to a direct table access, then return
+** a pointer to the SELECT statement.  If pX is not a SELECT statement,
+** or if the SELECT statement needs to be manifested into a transient
+** table, then return NULL.
 */
 #ifndef SQLITE_OMIT_SUBQUERY
-static int isCandidateForInOpt(Select *p){
+static Select *isCandidateForInOpt(Expr *pX){
+  Select *p;
   SrcList *pSrc;
   ExprList *pEList;
+  Expr *pRes;
   Table *pTab;
-  if( p==0 ) return 0;                   /* right-hand side of IN is SELECT */
+  if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0;  /* Not a subquery */
+  if( ExprHasProperty(pX, EP_VarSelect)  ) return 0;  /* Correlated subq */
+  p = pX->x.pSelect;
   if( p->pPrior ) return 0;              /* Not a compound SELECT */
   if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
     testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
@@ -88233,13 +90739,15 @@ static int isCandidateForInOpt(Select *p){
   if( pSrc->nSrc!=1 ) return 0;          /* Single term in FROM clause */
   if( pSrc->a[0].pSelect ) return 0;     /* FROM is not a subquery or view */
   pTab = pSrc->a[0].pTab;
-  if( NEVER(pTab==0) ) return 0;
+  assert( pTab!=0 );
   assert( pTab->pSelect==0 );            /* FROM clause is not a view */
   if( IsVirtual(pTab) ) return 0;        /* FROM clause not a virtual table */
   pEList = p->pEList;
   if( pEList->nExpr!=1 ) return 0;       /* One column in the result set */
-  if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
-  return 1;
+  pRes = pEList->a[0].pExpr;
+  if( pRes->op!=TK_COLUMN ) return 0;    /* Result is a column */
+  assert( pRes->iTable==pSrc->a[0].iCursor );  /* Not a correlated subquery */
+  return p;
 }
 #endif /* SQLITE_OMIT_SUBQUERY */
 
@@ -88371,15 +90879,13 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
   ** satisfy the query.  This is preferable to generating a new 
   ** ephemeral table.
   */
-  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
-  if( pParse->nErr==0 && isCandidateForInOpt(p) ){
+  if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
     sqlite3 *db = pParse->db;              /* Database connection */
     Table *pTab;                           /* Table <table>. */
     Expr *pExpr;                           /* Expression <column> */
     i16 iCol;                              /* Index of column <column> */
     i16 iDb;                               /* Database idx for pTab */
 
-    assert( p );                        /* Because of isCandidateForInOpt(p) */
     assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
     assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
     assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
@@ -88949,6 +91455,19 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
   }
 }
 
+#if defined(SQLITE_DEBUG)
+/*
+** Verify the consistency of the column cache
+*/
+static int cacheIsValid(Parse *pParse){
+  int i, n;
+  for(i=n=0; i<SQLITE_N_COLCACHE; i++){
+    if( pParse->aColCache[i].iReg>0 ) n++;
+  }
+  return n==pParse->nColCache;
+}
+#endif
+
 /*
 ** Clear a cache entry.
 */
@@ -88959,6 +91478,9 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){
     }
     p->tempReg = 0;
   }
+  p->iReg = 0;
+  pParse->nColCache--;
+  assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
 }
 
 
@@ -89002,6 +91524,8 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
       p->iReg = iReg;
       p->tempReg = 0;
       p->lru = pParse->iCacheCnt++;
+      pParse->nColCache++;
+      assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
       return;
     }
   }
@@ -89023,6 +91547,7 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
     p->iReg = iReg;
     p->tempReg = 0;
     p->lru = pParse->iCacheCnt++;
+    assert( cacheIsValid(pParse) );
     return;
   }
 }
@@ -89032,15 +91557,13 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
 ** Purge the range of registers from the column cache.
 */
 SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
-  int i;
-  int iLast = iReg + nReg - 1;
   struct yColCache *p;
-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
-    int r = p->iReg;
-    if( r>=iReg && r<=iLast ){
-      cacheEntryClear(pParse, p);
-      p->iReg = 0;
-    }
+  if( iReg<=0 || pParse->nColCache==0 ) return;
+  p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
+  while(1){
+    if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);
+    if( p==pParse->aColCache ) break;
+    p--;
   }
 }
 
@@ -89076,7 +91599,6 @@ SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
   for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
     if( p->iReg && p->iLevel>pParse->iCacheLevel ){
       cacheEntryClear(pParse, p);
-      p->iReg = 0;
     }
   }
 }
@@ -89211,7 +91733,6 @@ SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
   for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
     if( p->iReg ){
       cacheEntryClear(pParse, p);
-      p->iReg = 0;
     }
   }
 }
@@ -89253,6 +91774,7 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
 }
 #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
 
+
 /*
 ** Convert an expression node to a TK_REGISTER
 */
@@ -89521,7 +92043,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
       ExprList *pFarg;       /* List of function arguments */
       int nFarg;             /* Number of function arguments */
       FuncDef *pDef;         /* The function definition object */
-      int nId;               /* Length of the function name in bytes */
       const char *zId;       /* The function name */
       u32 constMask = 0;     /* Mask of function arguments that are constant */
       int i;                 /* Loop counter */
@@ -89537,10 +92058,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
       nFarg = pFarg ? pFarg->nExpr : 0;
       assert( !ExprHasProperty(pExpr, EP_IntValue) );
       zId = pExpr->u.zToken;
-      nId = sqlite3Strlen30(zId);
-      pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
+      pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
       if( pDef==0 || pDef->xFinalize!=0 ){
-        sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
+        sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
         break;
       }
 
@@ -89705,6 +92225,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
       sqlite3ReleaseTempReg(pParse, r4);
       break;
     }
+    case TK_SPAN:
     case TK_COLLATE: 
     case TK_UPLUS: {
       inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
@@ -90183,6 +92704,13 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
       sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
       break;
     }
+    case TK_IS:
+    case TK_ISNOT:
+      testcase( op==TK_IS );
+      testcase( op==TK_ISNOT );
+      op = (op==TK_IS) ? TK_EQ : TK_NE;
+      jumpIfNull = SQLITE_NULLEQ;
+      /* Fall thru */
     case TK_LT:
     case TK_LE:
     case TK_GT:
@@ -90198,23 +92726,12 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
       assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
       assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
       assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
-      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
-      assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
-      testcase( regFree1==0 );
-      testcase( regFree2==0 );
-      break;
-    }
-    case TK_IS:
-    case TK_ISNOT: {
-      testcase( op==TK_IS );
-      testcase( op==TK_ISNOT );
-      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
-      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
-      op = (op==TK_IS) ? TK_EQ : TK_NE;
-      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
-                  r1, r2, dest, SQLITE_NULLEQ);
-      VdbeCoverageIf(v, op==TK_EQ);
-      VdbeCoverageIf(v, op==TK_NE);
+      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
+      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
+      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
+      assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
+      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
+      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
       testcase( regFree1==0 );
       testcase( regFree2==0 );
       break;
@@ -90339,6 +92856,13 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
       sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
       break;
     }
+    case TK_IS:
+    case TK_ISNOT:
+      testcase( pExpr->op==TK_IS );
+      testcase( pExpr->op==TK_ISNOT );
+      op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
+      jumpIfNull = SQLITE_NULLEQ;
+      /* Fall thru */
     case TK_LT:
     case TK_LE:
     case TK_GT:
@@ -90354,23 +92878,12 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
       assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
       assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
       assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
-      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
-      assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
-      testcase( regFree1==0 );
-      testcase( regFree2==0 );
-      break;
-    }
-    case TK_IS:
-    case TK_ISNOT: {
-      testcase( pExpr->op==TK_IS );
-      testcase( pExpr->op==TK_ISNOT );
-      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
-      r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
-      op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
-      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
-                  r1, r2, dest, SQLITE_NULLEQ);
-      VdbeCoverageIf(v, op==TK_EQ);
-      VdbeCoverageIf(v, op==TK_NE);
+      assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
+      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
+      VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
+      assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
+      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
+      VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
       testcase( regFree1==0 );
       testcase( regFree2==0 );
       break;
@@ -90765,7 +93278,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
             pItem->iMem = ++pParse->nMem;
             assert( !ExprHasProperty(pExpr, EP_IntValue) );
             pItem->pFunc = sqlite3FindFunction(pParse->db,
-                   pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
+                   pExpr->u.zToken, 
                    pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
             if( pExpr->flags & EP_Distinct ){
               pItem->iDistinct = pParse->nTab++;
@@ -90894,6 +93407,29 @@ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){
   pParse->nRangeReg = 0;
 }
 
+/*
+** Validate that no temporary register falls within the range of
+** iFirst..iLast, inclusive.  This routine is only call from within assert()
+** statements.
+*/
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
+  int i;
+  if( pParse->nRangeReg>0
+   && pParse->iRangeReg+pParse->nRangeReg<iLast
+   && pParse->iRangeReg>=iFirst
+  ){
+     return 0;
+  }
+  for(i=0; i<pParse->nTempReg; i++){
+    if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){
+      return 0;
+    }
+  }
+  return 1;
+}
+#endif /* SQLITE_DEBUG */
+
 /************** End of expr.c ************************************************/
 /************** Begin file alter.c *******************************************/
 /*
@@ -91127,7 +93663,7 @@ static void renameTriggerFunc(
 ** Register built-in functions used to help implement ALTER TABLE
 */
 SQLITE_PRIVATE void sqlite3AlterFunctions(void){
-  static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
+  static FuncDef aAlterTableFuncs[] = {
     FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
 #ifndef SQLITE_OMIT_TRIGGER
     FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
@@ -91136,13 +93672,7 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void){
     FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
 #endif
   };
-  int i;
-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
-
-  for(i=0; i<ArraySize(aAlterTableFuncs); i++){
-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
-  }
+  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
 }
 
 /*
@@ -91296,7 +93826,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
   Token *pName              /* The new table name. */
 ){
   int iDb;                  /* Database that contains the table */
-  char *zDb;                /* Name of database iDb */
+  const char *zDb;          /* Name of database iDb */
   Table *pTab;              /* Table being renamed */
   char *zName = 0;          /* NULL-terminated version of pName */ 
   sqlite3 *db = pParse->db; /* Database connection */
@@ -91532,7 +94062,8 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
   ** literal NULL, then set pDflt to 0. This simplifies checking
   ** for an SQL NULL default below.
   */
-  if( pDflt && pDflt->op==TK_NULL ){
+  assert( pDflt==0 || pDflt->op==TK_SPAN );
+  if( pDflt && pDflt->pLeft->op==TK_NULL ){
     pDflt = 0;
   }
 
@@ -91689,9 +94220,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
     Column *pCol = &pNew->aCol[i];
     pCol->zName = sqlite3DbStrDup(db, pCol->zName);
     pCol->zColl = 0;
-    pCol->zType = 0;
     pCol->pDflt = 0;
-    pCol->zDflt = 0;
   }
   pNew->pSchema = db->aDb[iDb].pSchema;
   pNew->addColOffset = pTab->addColOffset;
@@ -92194,8 +94723,7 @@ static const FuncDef statInitFuncdef = {
   statInit,        /* xSFunc */
   0,               /* xFinalize */
   "stat_init",     /* zName */
-  0,               /* pHash */
-  0                /* pDestructor */
+  {0}
 };
 
 #ifdef SQLITE_ENABLE_STAT4
@@ -92494,8 +95022,7 @@ static const FuncDef statPushFuncdef = {
   statPush,        /* xSFunc */
   0,               /* xFinalize */
   "stat_push",     /* zName */
-  0,               /* pHash */
-  0                /* pDestructor */
+  {0}
 };
 
 #define STAT_GET_STAT1 0          /* "stat" column of stat1 table */
@@ -92640,8 +95167,7 @@ static const FuncDef statGetFuncdef = {
   statGet,         /* xSFunc */
   0,               /* xFinalize */
   "stat_get",      /* zName */
-  0,               /* pHash */
-  0                /* pDestructor */
+  {0}
 };
 
 static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
@@ -93060,7 +95586,8 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
   sqlite3 *db = pParse->db;
   int iDb;
   int i;
-  char *z, *zDb;
+  char *z;
+  const char *zDb;
   Table *pTab;
   Index *pIdx;
   Token *pTableName;
@@ -93386,7 +95913,7 @@ static int loadStatTbl(
   assert( db->lookaside.bDisable );
   zSql = sqlite3MPrintf(db, zSql1, zDb);
   if( !zSql ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
   sqlite3DbFree(db, zSql);
@@ -93426,7 +95953,7 @@ static int loadStatTbl(
     pIdx->aSample = sqlite3DbMallocZero(db, nByte);
     if( pIdx->aSample==0 ){
       sqlite3_finalize(pStmt);
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     pSpace = (tRowcnt*)&pIdx->aSample[nSample];
     pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
@@ -93442,7 +95969,7 @@ static int loadStatTbl(
 
   zSql = sqlite3MPrintf(db, zSql2, zDb);
   if( !zSql ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
   sqlite3DbFree(db, zSql);
@@ -93480,7 +96007,7 @@ static int loadStatTbl(
     pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
     if( pSample->p==0 ){
       sqlite3_finalize(pStmt);
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
     pIdx->nSample++;
@@ -93542,7 +96069,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
   analysisInfo sInfo;
   HashElem *i;
   char *zSql;
-  int rc;
+  int rc = SQLITE_OK;
 
   assert( iDb>=0 && iDb<db->nDb );
   assert( db->aDb[iDb].pBt!=0 );
@@ -93551,31 +96078,34 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
     Index *pIdx = sqliteHashData(i);
-    sqlite3DefaultRowEst(pIdx);
+    pIdx->aiRowLogEst[0] = 0;
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
     sqlite3DeleteIndexSamples(db, pIdx);
     pIdx->aSample = 0;
 #endif
   }
 
-  /* Check to make sure the sqlite_stat1 table exists */
+  /* Load new statistics out of the sqlite_stat1 table */
   sInfo.db = db;
   sInfo.zDatabase = db->aDb[iDb].zName;
-  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
-    return SQLITE_ERROR;
+  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
+    zSql = sqlite3MPrintf(db, 
+        "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
+    if( zSql==0 ){
+      rc = SQLITE_NOMEM_BKPT;
+    }else{
+      rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
+      sqlite3DbFree(db, zSql);
+    }
   }
 
-  /* Load new statistics out of the sqlite_stat1 table */
-  zSql = sqlite3MPrintf(db, 
-      "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
-  if( zSql==0 ){
-    rc = SQLITE_NOMEM;
-  }else{
-    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
-    sqlite3DbFree(db, zSql);
+  /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
+  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+    Index *pIdx = sqliteHashData(i);
+    if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
   }
 
-
   /* Load the statistics from the sqlite_stat4 table. */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
@@ -93700,7 +96230,7 @@ static void attachFunc(
     goto attach_error;
   }
   for(i=0; i<db->nDb; i++){
-    char *z = db->aDb[i].zName;
+    const char *z = db->aDb[i].zName;
     assert( z && zName );
     if( sqlite3StrICmp(z, zName)==0 ){
       zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
@@ -93747,7 +96277,7 @@ static void attachFunc(
     Pager *pPager;
     aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
     if( !aNew->pSchema ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
       zErrDyn = sqlite3MPrintf(db, 
         "attached databases must use the same text encoding as main database");
@@ -93764,10 +96294,10 @@ static void attachFunc(
 #endif
     sqlite3BtreeLeave(aNew->pBt);
   }
-  aNew->safety_level = 3;
+  aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
   aNew->zName = sqlite3DbStrDup(db, zName);
   if( rc==SQLITE_OK && aNew->zName==0 ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }
 
 
@@ -93995,8 +96525,7 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
     detachFunc,       /* xSFunc */
     0,                /* xFinalize */
     "sqlite_detach",  /* zName */
-    0,                /* pHash */
-    0                 /* pDestructor */
+    {0}
   };
   codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
 }
@@ -94015,8 +96544,7 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p
     attachFunc,       /* xSFunc */
     0,                /* xFinalize */
     "sqlite_attach",  /* zName */
-    0,                /* pHash */
-    0                 /* pDestructor */
+    {0}
   };
   codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
 }
@@ -94297,7 +96825,7 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(
   int iDb                         /* Index of containing database. */
 ){
   sqlite3 *db = pParse->db;       /* Database handle */
-  char *zDb = db->aDb[iDb].zName; /* Name of attached database */
+  const char *zDb = db->aDb[iDb].zName; /* Name of attached database */
   int rc;                         /* Auth callback return code */
 
   rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
@@ -94942,7 +97470,7 @@ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
   for(i=j=2; i<db->nDb; i++){
     struct Db *pDb = &db->aDb[i];
     if( pDb->pBt==0 ){
-      sqlite3DbFree(db, pDb->zName);
+      sqlite3DbFree(db, (char *)pDb->zName);
       pDb->zName = 0;
       continue;
     }
@@ -95023,8 +97551,6 @@ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
     for(i=0; i<pTable->nCol; i++, pCol++){
       sqlite3DbFree(db, pCol->zName);
       sqlite3ExprDelete(db, pCol->pDflt);
-      sqlite3DbFree(db, pCol->zDflt);
-      sqlite3DbFree(db, pCol->zType);
       sqlite3DbFree(db, pCol->zColl);
     }
     sqlite3DbFree(db, pTable->aCol);
@@ -95046,16 +97572,10 @@ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
 ** db parameter can be used with db->pnBytesFreed to measure the memory
 ** used by the Table object.
 */
-SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
+static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
   Index *pIndex, *pNext;
   TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
 
-  assert( !pTable || pTable->nRef>0 );
-
-  /* Do not delete the table until the reference count reaches zero. */
-  if( !pTable ) return;
-  if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
-
   /* Record the number of outstanding lookaside allocations in schema Tables
   ** prior to doing any free() operations.  Since schema Tables do not use
   ** lookaside, this number should not change. */
@@ -95095,6 +97615,13 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
   /* Verify that no lookaside memory was used by schema tables */
   assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
 }
+SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
+  /* Do not delete the table until the reference count reaches zero. */
+  if( !pTable ) return;
+  if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
+  deleteTable(db, pTable);
+}
+
 
 /*
 ** Unlink the given table from the hash tables and the delete the
@@ -95162,12 +97689,8 @@ SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
   int i = -1;         /* Database number */
   if( zName ){
     Db *pDb;
-    int n = sqlite3Strlen30(zName);
     for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
-      if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) && 
-          0==sqlite3StrICmp(pDb->zName, zName) ){
-        break;
-      }
+      if( 0==sqlite3StrICmp(pDb->zName, zName) ) break;
     }
   }
   return i;
@@ -95337,7 +97860,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
        SQLITE_CREATE_VIEW,
        SQLITE_CREATE_TEMP_VIEW
     };
-    char *zDb = db->aDb[iDb].zName;
+    const char *zDb = db->aDb[iDb].zName;
     if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
       goto begin_table_error;
     }
@@ -95356,7 +97879,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
   ** collisions.
   */
   if( !IN_DECLARE_VTAB ){
-    char *zDb = db->aDb[iDb].zName;
+    const char *zDb = db->aDb[iDb].zName;
     if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
       goto begin_table_error;
     }
@@ -95379,7 +97902,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
   pTable = sqlite3DbMallocZero(db, sizeof(Table));
   if( pTable==0 ){
     assert( db->mallocFailed );
-    pParse->rc = SQLITE_NOMEM;
+    pParse->rc = SQLITE_NOMEM_BKPT;
     pParse->nErr++;
     goto begin_table_error;
   }
@@ -95495,10 +98018,11 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
 ** first to get things going.  Then this routine is called for each
 ** column.
 */
-SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
+SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
   Table *p;
   int i;
   char *z;
+  char *zType;
   Column *pCol;
   sqlite3 *db = pParse->db;
   if( (p = pParse->pNewTable)==0 ) return;
@@ -95508,8 +98032,11 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
     return;
   }
 #endif
-  z = sqlite3NameFromToken(db, pName);
+  z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
   if( z==0 ) return;
+  memcpy(z, pName->z, pName->n);
+  z[pName->n] = 0;
+  sqlite3Dequote(z);
   for(i=0; i<p->nCol; i++){
     if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){
       sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
@@ -95531,13 +98058,21 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
   pCol->zName = z;
   sqlite3ColumnPropertiesFromName(p, pCol);
  
-  /* If there is no type specified, columns have the default affinity
-  ** 'BLOB'. If there is a type specified, then sqlite3AddColumnType() will
-  ** be called next to set pCol->affinity correctly.
-  */
-  pCol->affinity = SQLITE_AFF_BLOB;
-  pCol->szEst = 1;
+  if( pType->n==0 ){
+    /* If there is no type specified, columns have the default affinity
+    ** 'BLOB'. */
+    pCol->affinity = SQLITE_AFF_BLOB;
+    pCol->szEst = 1;
+  }else{
+    zType = z + sqlite3Strlen30(z) + 1;
+    memcpy(zType, pType->z, pType->n);
+    zType[pType->n] = 0;
+    sqlite3Dequote(zType);
+    pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
+    pCol->colFlags |= COLFLAG_HASTYPE;
+  }
   p->nCol++;
+  pParse->constraintName.n = 0;
 }
 
 /*
@@ -95583,7 +98118,7 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
   char aff = SQLITE_AFF_NUMERIC;
   const char *zChar = 0;
 
-  if( zIn==0 ) return aff;
+  assert( zIn!=0 );
   while( zIn[0] ){
     h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
     zIn++;
@@ -95641,28 +98176,6 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
 }
 
 /*
-** This routine is called by the parser while in the middle of
-** parsing a CREATE TABLE statement.  The pFirst token is the first
-** token in the sequence of tokens that describe the type of the
-** column currently under construction.   pLast is the last token
-** in the sequence.  Use this information to construct a string
-** that contains the typename of the column and store that string
-** in zType.
-*/ 
-SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
-  Table *p;
-  Column *pCol;
-
-  p = pParse->pNewTable;
-  if( p==0 || NEVER(p->nCol<1) ) return;
-  pCol = &p->aCol[p->nCol-1];
-  assert( pCol->zType==0 || CORRUPT_DB );
-  sqlite3DbFree(pParse->db, pCol->zType);
-  pCol->zType = sqlite3NameFromToken(pParse->db, pType);
-  pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
-}
-
-/*
 ** The expression is the default value for the most recently added column
 ** of the table currently under construction.
 **
@@ -95687,11 +98200,16 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
       ** tokens that point to volatile memory. The 'span' of the expression
       ** is required by pragma table_info.
       */
+      Expr x;
       sqlite3ExprDelete(db, pCol->pDflt);
-      pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
-      sqlite3DbFree(db, pCol->zDflt);
-      pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
-                                     (int)(pSpan->zEnd - pSpan->zStart));
+      memset(&x, 0, sizeof(x));
+      x.op = TK_SPAN;
+      x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
+                                    (int)(pSpan->zEnd - pSpan->zStart));
+      x.pLeft = pSpan->pExpr;
+      x.flags = EP_Skip;
+      pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
+      sqlite3DbFree(db, x.u.zToken);
     }
   }
   sqlite3ExprDelete(db, pSpan->pExpr);
@@ -95747,7 +98265,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
   int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
 ){
   Table *pTab = pParse->pNewTable;
-  char *zType = 0;
+  Column *pCol = 0;
   int iCol = -1, i;
   int nTerm;
   if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
@@ -95759,8 +98277,8 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
   pTab->tabFlags |= TF_HasPrimaryKey;
   if( pList==0 ){
     iCol = pTab->nCol - 1;
-    pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
-    zType = pTab->aCol[iCol].zType;
+    pCol = &pTab->aCol[iCol];
+    pCol->colFlags |= COLFLAG_PRIMKEY;
     nTerm = 1;
   }else{
     nTerm = pList->nExpr;
@@ -95772,8 +98290,8 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
         const char *zCName = pCExpr->u.zToken;
         for(iCol=0; iCol<pTab->nCol; iCol++){
           if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
-            pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
-            zType = pTab->aCol[iCol].zType;
+            pCol = &pTab->aCol[iCol];
+            pCol->colFlags |= COLFLAG_PRIMKEY;
             break;
           }
         }
@@ -95781,7 +98299,8 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
     }
   }
   if( nTerm==1
-   && zType && sqlite3StrICmp(zType, "INTEGER")==0
+   && pCol
+   && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
    && sortOrder!=SQLITE_SO_DESC
   ){
     pTab->iPKey = iCol;
@@ -95988,7 +98507,7 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){
 static char *createTableStmt(sqlite3 *db, Table *p){
   int i, k, n;
   char *zStmt;
-  char *zSep, *zSep2, *zEnd;
+  const char *zSep, *zSep2, *zEnd;
   Column *pCol;
   n = 0;
   for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
@@ -96060,7 +98579,7 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
   assert( pIdx->isResized==0 );
   nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
   zExtra = sqlite3DbMallocZero(db, nByte);
-  if( zExtra==0 ) return SQLITE_NOMEM;
+  if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
   memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
   pIdx->azColl = (const char**)zExtra;
   zExtra += sizeof(char*)*N;
@@ -96348,8 +98867,8 @@ SQLITE_PRIVATE void sqlite3EndTable(
   if( !db->init.busy ){
     int n;
     Vdbe *v;
-    char *zType;    /* "view" or "table" */
-    char *zType2;   /* "VIEW" or "TABLE" */
+    const char *zType;    /* "view" or "table" */
+    const char *zType2;   /* "VIEW" or "TABLE" */
     char *zStmt;    /* Text of the CREATE TABLE or CREATE VIEW statement */
 
     v = sqlite3GetVdbe(pParse);
@@ -96639,44 +99158,55 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
   ** statement that defines the view.
   */
   assert( pTable->pSelect );
-  if( pTable->pCheck ){
+  pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
+  if( pSel ){
+    n = pParse->nTab;
+    sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
+    pTable->nCol = -1;
     db->lookaside.bDisable++;
-    sqlite3ColumnsFromExprList(pParse, pTable->pCheck, 
-                               &pTable->nCol, &pTable->aCol);
-    db->lookaside.bDisable--;
-  }else{
-    pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
-    if( pSel ){
-      n = pParse->nTab;
-      sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
-      pTable->nCol = -1;
-      db->lookaside.bDisable++;
 #ifndef SQLITE_OMIT_AUTHORIZATION
-      xAuth = db->xAuth;
-      db->xAuth = 0;
-      pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
-      db->xAuth = xAuth;
+    xAuth = db->xAuth;
+    db->xAuth = 0;
+    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
+    db->xAuth = xAuth;
 #else
-      pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
-#endif
-      db->lookaside.bDisable--;
-      pParse->nTab = n;
-      if( pSelTab ){
-        assert( pTable->aCol==0 );
-        pTable->nCol = pSelTab->nCol;
-        pTable->aCol = pSelTab->aCol;
-        pSelTab->nCol = 0;
-        pSelTab->aCol = 0;
-        sqlite3DeleteTable(db, pSelTab);
-        assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
-      }else{
-        pTable->nCol = 0;
-        nErr++;
+    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
+#endif
+    pParse->nTab = n;
+    if( pTable->pCheck ){
+      /* CREATE VIEW name(arglist) AS ...
+      ** The names of the columns in the table are taken from
+      ** arglist which is stored in pTable->pCheck.  The pCheck field
+      ** normally holds CHECK constraints on an ordinary table, but for
+      ** a VIEW it holds the list of column names.
+      */
+      sqlite3ColumnsFromExprList(pParse, pTable->pCheck, 
+                                 &pTable->nCol, &pTable->aCol);
+      if( db->mallocFailed==0 
+       && pParse->nErr==0
+       && pTable->nCol==pSel->pEList->nExpr
+      ){
+        sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
       }
-      sqlite3SelectDelete(db, pSel);
-    } else {
+    }else if( pSelTab ){
+      /* CREATE VIEW name AS...  without an argument list.  Construct
+      ** the column names from the SELECT statement that defines the view.
+      */
+      assert( pTable->aCol==0 );
+      pTable->nCol = pSelTab->nCol;
+      pTable->aCol = pSelTab->aCol;
+      pSelTab->nCol = 0;
+      pSelTab->aCol = 0;
+      assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
+    }else{
+      pTable->nCol = 0;
       nErr++;
     }
+    sqlite3DeleteTable(db, pSelTab);
+    sqlite3SelectDelete(db, pSel);
+    db->lookaside.bDisable--;
+  } else {
+    nErr++;
   }
   pTable->pSchema->schemaFlags |= DB_UnresetViews;
 #endif /* SQLITE_OMIT_VIEW */
@@ -97225,6 +99755,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
     tnum = pIndex->tnum;
   }
   pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
+  assert( pKey!=0 || db->mallocFailed || pParse->nErr );
 
   /* Open the sorter cursor if we are to use one. */
   iSorter = pParse->nTab++;
@@ -97248,8 +99779,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
 
   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
-  assert( pKey!=0 || db->mallocFailed || pParse->nErr );
-  if( IsUniqueIndex(pIndex) && pKey!=0 ){
+  if( IsUniqueIndex(pIndex) ){
     int j2 = sqlite3VdbeCurrentAddr(v) + 3;
     sqlite3VdbeGoto(v, j2);
     addr2 = sqlite3VdbeCurrentAddr(v);
@@ -97652,6 +100182,20 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   sqlite3DefaultRowEst(pIndex);
   if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
 
+  /* If this index contains every column of its table, then mark
+  ** it as a covering index */
+  assert( HasRowid(pTab) 
+      || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
+  if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
+    pIndex->isCovering = 1;
+    for(j=0; j<pTab->nCol; j++){
+      if( j==pTab->iPKey ) continue;
+      if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
+      pIndex->isCovering = 0;
+      break;
+    }
+  }
+
   if( pTab==pParse->pNewTable ){
     /* This routine has been called to create an automatic index as a
     ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
@@ -97689,7 +100233,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
         if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
         z1 = pIdx->azColl[k];
         z2 = pIndex->azColl[k];
-        if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
+        if( sqlite3StrICmp(z1, z2) ) break;
       }
       if( k==pIdx->nKeyCol ){
         if( pIdx->onError!=pIndex->onError ){
@@ -99142,14 +101686,12 @@ static int matchQuality(
 ** a pointer to the matching FuncDef if found, or 0 if there is no match.
 */
 static FuncDef *functionSearch(
-  FuncDefHash *pHash,  /* Hash table to search */
   int h,               /* Hash of the name */
-  const char *zFunc,   /* Name of function */
-  int nFunc            /* Number of bytes in zFunc */
+  const char *zFunc    /* Name of function */
 ){
   FuncDef *p;
-  for(p=pHash->a[h]; p; p=p->pHash){
-    if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
+  for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
+    if( sqlite3StrICmp(p->zName, zFunc)==0 ){
       return p;
     }
   }
@@ -99159,23 +101701,26 @@ static FuncDef *functionSearch(
 /*
 ** Insert a new FuncDef into a FuncDefHash hash table.
 */
-SQLITE_PRIVATE void sqlite3FuncDefInsert(
-  FuncDefHash *pHash,  /* The hash table into which to insert */
-  FuncDef *pDef        /* The function definition to insert */
+SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
+  FuncDef *aDef,      /* List of global functions to be inserted */
+  int nDef            /* Length of the apDef[] list */
 ){
-  FuncDef *pOther;
-  int nName = sqlite3Strlen30(pDef->zName);
-  u8 c1 = (u8)pDef->zName[0];
-  int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
-  pOther = functionSearch(pHash, h, pDef->zName, nName);
-  if( pOther ){
-    assert( pOther!=pDef && pOther->pNext!=pDef );
-    pDef->pNext = pOther->pNext;
-    pOther->pNext = pDef;
-  }else{
-    pDef->pNext = 0;
-    pDef->pHash = pHash->a[h];
-    pHash->a[h] = pDef;
+  int i;
+  for(i=0; i<nDef; i++){
+    FuncDef *pOther;
+    const char *zName = aDef[i].zName;
+    int nName = sqlite3Strlen30(zName);
+    int h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+    pOther = functionSearch(h, zName);
+    if( pOther ){
+      assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
+      aDef[i].pNext = pOther->pNext;
+      pOther->pNext = &aDef[i];
+    }else{
+      aDef[i].pNext = 0;
+      aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
+      sqlite3BuiltinFunctions.a[h] = &aDef[i];
+    }
   }
 }
   
@@ -99202,8 +101747,7 @@ SQLITE_PRIVATE void sqlite3FuncDefInsert(
 */
 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
   sqlite3 *db,       /* An open database */
-  const char *zName, /* Name of the function.  Not null-terminated */
-  int nName,         /* Number of characters in the name */
+  const char *zName, /* Name of the function.  zero-terminated */
   int nArg,          /* Number of arguments.  -1 means any number */
   u8 enc,            /* Preferred text encoding */
   u8 createFlag      /* Create new entry if true and does not otherwise exist */
@@ -99212,14 +101756,15 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
   FuncDef *pBest = 0; /* Best match found so far */
   int bestScore = 0;  /* Score of best match */
   int h;              /* Hash value */
+  int nName;          /* Length of the name */
 
   assert( nArg>=(-2) );
   assert( nArg>=(-1) || createFlag==0 );
-  h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
+  nName = sqlite3Strlen30(zName);
 
   /* First search for a match amongst the application-defined functions.
   */
-  p = functionSearch(&db->aFunc, h, zName, nName);
+  p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
   while( p ){
     int score = matchQuality(p, nArg, enc);
     if( score>bestScore ){
@@ -99242,9 +101787,9 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
   ** So we must not search for built-ins when creating a new function.
   */ 
   if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
-    FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
     bestScore = 0;
-    p = functionSearch(pHash, h, zName, nName);
+    h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+    p = functionSearch(h, zName);
     while( p ){
       int score = matchQuality(p, nArg, enc);
       if( score>bestScore ){
@@ -99261,12 +101806,19 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
   */
   if( createFlag && bestScore<FUNC_PERFECT_MATCH && 
       (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
-    pBest->zName = (char *)&pBest[1];
+    FuncDef *pOther;
+    pBest->zName = (const char*)&pBest[1];
     pBest->nArg = (u16)nArg;
     pBest->funcFlags = enc;
-    memcpy(pBest->zName, zName, nName);
-    pBest->zName[nName] = 0;
-    sqlite3FuncDefInsert(&db->aFunc, pBest);
+    memcpy((char*)&pBest[1], zName, nName+1);
+    pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
+    if( pOther==pBest ){
+      sqlite3DbFree(db, pBest);
+      sqlite3OomFault(db);
+      return 0;
+    }else{
+      pBest->pNext = pOther;
+    }
   }
 
   if( pBest && (pBest->xSFunc || createFlag) ){
@@ -99468,7 +102020,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
   ExprList *pOrderBy,          /* The ORDER BY clause.  May be null */
   Expr *pLimit,                /* The LIMIT clause.  May be null */
   Expr *pOffset,               /* The OFFSET clause.  May be null */
-  char *zStmtType              /* Either DELETE or UPDATE.  For err msgs. */
+  const char *zStmtType        /* Either DELETE or UPDATE.  For err msgs. */
 ){
   Expr *pWhereRowid = NULL;    /* WHERE rowid .. */
   Expr *pInClause = NULL;      /* WHERE rowid IN ( select ) */
@@ -99481,7 +102033,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
   */
   if( pOrderBy && (pLimit == 0) ) {
     sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
-    goto limit_where_cleanup_2;
+    goto limit_where_cleanup;
   }
 
   /* We only need to generate a select expression if there
@@ -99503,16 +102055,16 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
   */
 
   pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
-  if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
+  if( pSelectRowid == 0 ) goto limit_where_cleanup;
   pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
-  if( pEList == 0 ) goto limit_where_cleanup_2;
+  if( pEList == 0 ) goto limit_where_cleanup;
 
   /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
   ** and the SELECT subtree. */
   pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
   if( pSelectSrc == 0 ) {
     sqlite3ExprListDelete(pParse->db, pEList);
-    goto limit_where_cleanup_2;
+    goto limit_where_cleanup;
   }
 
   /* generate the SELECT expression tree. */
@@ -99522,21 +102074,11 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
 
   /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
   pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
-  if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
-  pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
-  if( pInClause == 0 ) goto limit_where_cleanup_1;
-
-  pInClause->x.pSelect = pSelect;
-  pInClause->flags |= EP_xIsSelect;
-  sqlite3ExprSetHeightAndFlags(pParse, pInClause);
+  pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0;
+  sqlite3PExprAddSelect(pParse, pInClause, pSelect);
   return pInClause;
 
-  /* something went wrong. clean up anything allocated. */
-limit_where_cleanup_1:
-  sqlite3SelectDelete(pParse->db, pSelect);
-  return 0;
-
-limit_where_cleanup_2:
+limit_where_cleanup:
   sqlite3ExprDelete(pParse->db, pWhere);
   sqlite3ExprListDelete(pParse->db, pOrderBy);
   sqlite3ExprDelete(pParse->db, pLimit);
@@ -99587,11 +102129,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
   int addrBypass = 0;    /* Address of jump over the delete logic */
   int addrLoop = 0;      /* Top of the delete loop */
   int addrEphOpen = 0;   /* Instruction to open the Ephemeral table */
+  int bComplex;          /* True if there are triggers or FKs or
+                         ** subqueries in the WHERE clause */
  
 #ifndef SQLITE_OMIT_TRIGGER
   int isView;                  /* True if attempting to delete from a view */
   Trigger *pTrigger;           /* List of table triggers, if required */
-  int bComplex;                /* True if there are either triggers or FKs */
 #endif
 
   memset(&sContext, 0, sizeof(sContext));
@@ -99619,7 +102162,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
 #else
 # define pTrigger 0
 # define isView 0
-# define bComplex 0
 #endif
 #ifdef SQLITE_OMIT_VIEW
 # undef isView
@@ -99704,6 +102246,9 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
    && pWhere==0
    && !bComplex
    && !IsVirtual(pTab)
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+   && db->xPreUpdateCallback==0
+#endif
   ){
     assert( !isView );
     sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
@@ -99718,7 +102263,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
   }else
 #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
   {
-    u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
+    u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE;
+    if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
     wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
     if( HasRowid(pTab) ){
       /* For a rowid table, initialize the RowSet to an empty set */
@@ -100053,14 +102599,19 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
 
   /* Delete the index and table entries. Skip this step if pTab is really
   ** a view (in which case the only effect of the DELETE statement is to
-  ** fire the INSTEAD OF triggers).  */ 
+  ** fire the INSTEAD OF triggers).  
+  **
+  ** If variable 'count' is non-zero, then this OP_Delete instruction should
+  ** invoke the update-hook. The pre-update-hook, on the other hand should
+  ** be invoked unless table pTab is a system table. The difference is that
+  ** the update-hook is not invoked for rows removed by REPLACE, but the 
+  ** pre-update-hook is.
+  */ 
   if( pTab->pSelect==0 ){
     u8 p5 = 0;
     sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
     sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
-    if( count ){
-      sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
-    }
+    sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE);
     if( eMode!=ONEPASS_OFF ){
       sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
     }
@@ -101625,6 +104176,14 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
   sqlite3 *db = sqlite3_context_db_handle(context);
   char *zErrMsg = 0;
 
+  /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
+  ** flag is set.  See the sqlite3_enable_load_extension() API.
+  */
+  if( (db->flags & SQLITE_LoadExtFunc)==0 ){
+    sqlite3_result_error(context, "not authorized", -1);
+    return;
+  }
+
   if( argc==2 ){
     zProc = (const char *)sqlite3_value_text(argv[1]);
   }else{
@@ -101850,7 +104409,7 @@ static void groupConcatFinalize(sqlite3_context *context){
 ** of the built-in functions above are part of the global function set.
 ** This routine only deals with those that are not global.
 */
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
+SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
   int rc = sqlite3_overload_function(db, "MATCH", 2);
   assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
   if( rc==SQLITE_NOMEM ){
@@ -101863,8 +104422,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
 */
 static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
   FuncDef *pDef;
-  pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
-                             2, SQLITE_UTF8, 0);
+  pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
   if( ALWAYS(pDef) ){
     pDef->funcFlags |= flagVal;
   }
@@ -101912,9 +104470,7 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
     return 0;
   }
   assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
-  pDef = sqlite3FindFunction(db, pExpr->u.zToken, 
-                             sqlite3Strlen30(pExpr->u.zToken),
-                             2, SQLITE_UTF8, 0);
+  pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
   if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
     return 0;
   }
@@ -101938,7 +104494,7 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
 **
 ** After this routine runs
 */
-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
+SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
   /*
   ** The following array holds FuncDef structures for all of the functions
   ** defined in this file.
@@ -101946,8 +104502,27 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
   ** The array cannot be constant since changes are made to the
   ** FuncDef.pHash elements at start-time.  The elements of this array
   ** are read-only after initialization is complete.
+  **
+  ** For peak efficiency, put the most frequently used function last.
   */
-  static SQLITE_WSD FuncDef aBuiltinFunc[] = {
+  static FuncDef aBuiltinFunc[] = {
+#ifdef SQLITE_SOUNDEX
+    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
+#endif
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+    VFUNCTION(load_extension,    1, 0, 0, loadExt          ),
+    VFUNCTION(load_extension,    2, 0, 0, loadExt          ),
+#endif
+#if SQLITE_USER_AUTHENTICATION
+    FUNCTION(sqlite_crypt,       2, 0, 0, sqlite3CryptFunc ),
+#endif
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+    DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
+    DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+    FUNCTION2(unlikely,          1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
+    FUNCTION2(likelihood,        2, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
+    FUNCTION2(likely,            1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
     FUNCTION(ltrim,              1, 1, 0, trimFunc         ),
     FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
     FUNCTION(rtrim,              1, 2, 0, trimFunc         ),
@@ -101965,8 +104540,6 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
     FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
     FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
     FUNCTION(instr,              2, 0, 0, instrFunc        ),
-    FUNCTION(substr,             2, 0, 0, substrFunc       ),
-    FUNCTION(substr,             3, 0, 0, substrFunc       ),
     FUNCTION(printf,            -1, 0, 0, printfFunc       ),
     FUNCTION(unicode,            1, 0, 0, unicodeFunc      ),
     FUNCTION(char,              -1, 0, 0, charFunc         ),
@@ -101977,40 +104550,22 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
 #endif
     FUNCTION(upper,              1, 0, 0, upperFunc        ),
     FUNCTION(lower,              1, 0, 0, lowerFunc        ),
-    FUNCTION(coalesce,           1, 0, 0, 0                ),
-    FUNCTION(coalesce,           0, 0, 0, 0                ),
-    FUNCTION2(coalesce,         -1, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
     FUNCTION(hex,                1, 0, 0, hexFunc          ),
     FUNCTION2(ifnull,            2, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
-    FUNCTION2(unlikely,          1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
-    FUNCTION2(likelihood,        2, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
-    FUNCTION2(likely,            1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
     VFUNCTION(random,            0, 0, 0, randomFunc       ),
     VFUNCTION(randomblob,        1, 0, 0, randomBlob       ),
     FUNCTION(nullif,             2, 0, 1, nullifFunc       ),
     DFUNCTION(sqlite_version,    0, 0, 0, versionFunc      ),
     DFUNCTION(sqlite_source_id,  0, 0, 0, sourceidFunc     ),
     FUNCTION(sqlite_log,         2, 0, 0, errlogFunc       ),
-#if SQLITE_USER_AUTHENTICATION
-    FUNCTION(sqlite_crypt,       2, 0, 0, sqlite3CryptFunc ),
-#endif
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-    DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
-    DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
     FUNCTION(quote,              1, 0, 0, quoteFunc        ),
     VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
     VFUNCTION(changes,           0, 0, 0, changes          ),
     VFUNCTION(total_changes,     0, 0, 0, total_changes    ),
     FUNCTION(replace,            3, 0, 0, replaceFunc      ),
     FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
-  #ifdef SQLITE_SOUNDEX
-    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
-  #endif
-  #ifndef SQLITE_OMIT_LOAD_EXTENSION
-    VFUNCTION(load_extension,    1, 0, 0, loadExt          ),
-    VFUNCTION(load_extension,    2, 0, 0, loadExt          ),
-  #endif
+    FUNCTION(substr,             2, 0, 0, substrFunc       ),
+    FUNCTION(substr,             3, 0, 0, substrFunc       ),
     AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),
     AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),
     AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),
@@ -102028,22 +104583,34 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
     LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
     LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
   #endif
+    FUNCTION(coalesce,           1, 0, 0, 0                ),
+    FUNCTION(coalesce,           0, 0, 0, 0                ),
+    FUNCTION2(coalesce,         -1, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
   };
-
-  int i;
-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);
-
-  for(i=0; i<ArraySize(aBuiltinFunc); i++){
-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
-  }
-  sqlite3RegisterDateTimeFunctions();
 #ifndef SQLITE_OMIT_ALTERTABLE
   sqlite3AlterFunctions();
 #endif
 #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
   sqlite3AnalyzeFunctions();
 #endif
+  sqlite3RegisterDateTimeFunctions();
+  sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
+
+#if 0  /* Enable to print out how the built-in functions are hashed */
+  {
+    int i;
+    FuncDef *p;
+    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
+      printf("FUNC-HASH %02d:", i);
+      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
+        int n = sqlite3Strlen30(p->zName);
+        int h = p->zName[0] + n;
+        printf(" %s(%d)", p->zName, h);
+      }
+      printf("\n");
+    }
+  }
+#endif
 }
 
 /************** End of func.c ************************************************/
@@ -103212,6 +105779,9 @@ static Trigger *fkActionTrigger(
   int iAction = (pChanges!=0);    /* 1 for UPDATE, 0 for DELETE */
 
   action = pFKey->aAction[iAction];
+  if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){
+    return 0;
+  }
   pTrigger = pFKey->apTrigger[iAction];
 
   if( action!=OE_None && !pTrigger ){
@@ -104888,9 +107458,18 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
         if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
           sqlite3MultiWrite(pParse);
           sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
-                                   regNewData, 1, 0, OE_Replace,
-                                   ONEPASS_SINGLE, -1);
+                                   regNewData, 1, 0, OE_Replace, 1, -1);
         }else{
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+          if( HasRowid(pTab) ){
+            /* This OP_Delete opcode fires the pre-update-hook only. It does
+            ** not modify the b-tree. It is more efficient to let the coming
+            ** OP_Insert replace the existing entry than it is to delete the
+            ** existing entry and then insert a new one. */
+            sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
+            sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE);
+          }
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
           if( pTab->pIndex ){
             sqlite3MultiWrite(pParse);
             sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1);
@@ -105160,7 +107739,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
   }
   sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
   if( !pParse->nested ){
-    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
+    sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE);
   }
   sqlite3VdbeChangeP5(v, pik_flags);
 }
@@ -105456,11 +108035,15 @@ static int xferOptimization(
       return 0;    /* tab2 must be NOT NULL if tab1 is */
     }
     /* Default values for second and subsequent columns need to match. */
-    if( i>0
-     && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0) 
-         || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0))
-    ){
-      return 0;    /* Default values must be the same for all columns */
+    if( i>0 ){
+      assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
+      assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
+      if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) 
+       || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
+                                       pSrcCol->pDflt->u.zToken)!=0)
+      ){
+        return 0;    /* Default values must be the same for all columns */
+      }
     }
   }
   for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
@@ -105556,7 +108139,7 @@ static int xferOptimization(
     }
     sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
     sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid,
-                      pDest->zName, 0);
+                      (char*)pDest, P4_TABLE);
     sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
     sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
     sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -105765,7 +108348,7 @@ exec_out:
     if( *pzErrMsg ){
       memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
     }else{
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
       sqlite3Error(db, SQLITE_NOMEM);
     }
   }else if( pzErrMsg ){
@@ -106080,6 +108663,8 @@ struct sqlite3_api_routines {
   int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
   int (*strlike)(const char*,const char*,unsigned int);
   int (*db_cacheflush)(sqlite3*);
+  /* Version 3.12.0 and later */
+  int (*system_errno)(sqlite3*);
 };
 
 /*
@@ -106323,6 +108908,8 @@ struct sqlite3_api_routines {
 #define sqlite3_status64               sqlite3_api->status64
 #define sqlite3_strlike                sqlite3_api->strlike
 #define sqlite3_db_cacheflush          sqlite3_api->db_cacheflush
+/* Version 3.12.0 and later */
+#define sqlite3_system_errno           sqlite3_api->system_errno
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -106754,7 +109341,9 @@ static const sqlite3_api_routines sqlite3Apis = {
   /* Version 3.10.0 and later */
   sqlite3_status64,
   sqlite3_strlike,
-  sqlite3_db_cacheflush
+  sqlite3_db_cacheflush,
+  /* Version 3.12.0 and later */
+  sqlite3_system_errno
 };
 
 /*
@@ -106802,8 +109391,9 @@ static int sqlite3LoadExtension(
   /* Ticket #1863.  To avoid a creating security problems for older
   ** applications that relink against newer versions of SQLite, the
   ** ability to run load_extension is turned off by default.  One
-  ** must call sqlite3_enable_load_extension() to turn on extension
-  ** loading.  Otherwise you get the following error.
+  ** must call either sqlite3_enable_load_extension(db) or
+  ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
+  ** to turn on extension loading.
   */
   if( (db->flags & SQLITE_LoadExtension)==0 ){
     if( pzErrMsg ){
@@ -106817,7 +109407,7 @@ static int sqlite3LoadExtension(
   handle = sqlite3OsDlOpen(pVfs, zFile);
   for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
     char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
-    if( zAltFile==0 ) return SQLITE_NOMEM;
+    if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
     handle = sqlite3OsDlOpen(pVfs, zAltFile);
     sqlite3_free(zAltFile);
     if( handle!=0 ) break;
@@ -106863,7 +109453,7 @@ static int sqlite3LoadExtension(
     zAltEntry = sqlite3_malloc64(ncFile+30);
     if( zAltEntry==0 ){
       sqlite3OsDlClose(pVfs, handle);
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     memcpy(zAltEntry, "sqlite3_", 8);
     for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
@@ -106906,7 +109496,7 @@ static int sqlite3LoadExtension(
   /* Append the new shared library handle to the db->aExtension array. */
   aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
   if( aHandle==0 ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   if( db->nExtension>0 ){
     memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
@@ -106951,9 +109541,9 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
 SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){
   sqlite3_mutex_enter(db->mutex);
   if( onoff ){
-    db->flags |= SQLITE_LoadExtension;
+    db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
   }else{
-    db->flags &= ~SQLITE_LoadExtension;
+    db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
   }
   sqlite3_mutex_leave(db->mutex);
   return SQLITE_OK;
@@ -107028,7 +109618,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
       void (**aNew)(void);
       aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
       if( aNew==0 ){
-        rc = SQLITE_NOMEM;
+        rc = SQLITE_NOMEM_BKPT;
       }else{
         wsdAutoext.aExt = aNew;
         wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
@@ -107862,7 +110452,7 @@ static const char *actionName(u8 action){
 ** journal-mode name.
 */
 SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){
-  static char * const azModeName[] = {
+  static const char * const azModeName[] = {
     "delete", "persist", "off", "truncate", "memory"
 #ifndef SQLITE_OMIT_WAL
      , "wal"
@@ -108596,6 +111186,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
         int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
         if( iLevel==0 ) iLevel = 1;
         pDb->safety_level = iLevel;
+        pDb->bSyncSet = 1;
         setAllPagerFlags(db);
       }
     }
@@ -108679,12 +111270,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
         }else{
           for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
         }
+        assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
         sqlite3VdbeMultiLoad(v, 1, "issisi",
                i-nHidden,
                pCol->zName,
-               pCol->zType ? pCol->zType : "",
+               sqlite3ColumnType(pCol,""),
                pCol->notNull ? 1 : 0,
-               pCol->zDflt,
+               pCol->pDflt ? pCol->pDflt->u.zToken : 0,
                k);
         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
       }
@@ -108705,14 +111297,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
       sqlite3VdbeMultiLoad(v, 1, "ssii",
            pTab->zName,
            0,
-           (int)sqlite3LogEstToInt(pTab->szTabRow),
-           (int)sqlite3LogEstToInt(pTab->nRowLogEst));
+           pTab->szTabRow,
+           pTab->nRowLogEst);
       sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
         sqlite3VdbeMultiLoad(v, 2, "sii",
            pIdx->zName,
-           (int)sqlite3LogEstToInt(pIdx->szIdxRow),
-           (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]));
+           pIdx->szIdxRow,
+           pIdx->aiRowLogEst[0]);
         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
       }
     }
@@ -109038,7 +111630,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
     for(i=0; i<db->nDb; i++){
       HashElem *x;
       Hash *pTbls;
+      int *aRoot;
       int cnt = 0;
+      int mxIdx = 0;
+      int nIdx;
 
       if( OMIT_TEMPDB && i==1 ) continue;
       if( iDb>=0 && i!=iDb ) continue;
@@ -109051,31 +111646,35 @@ SQLITE_PRIVATE void sqlite3Pragma(
 
       /* Do an integrity check of the B-Tree
       **
-      ** Begin by filling registers 2, 3, ... with the root pages numbers
+      ** Begin by finding the root pages numbers
       ** for all tables and indices in the database.
       */
       assert( sqlite3SchemaMutexHeld(db, i, 0) );
       pTbls = &db->aDb[i].pSchema->tblHash;
-      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+      for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
         Table *pTab = sqliteHashData(x);
         Index *pIdx;
-        if( HasRowid(pTab) ){
-          sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
-          VdbeComment((v, "%s", pTab->zName));
-          cnt++;
-        }
+        if( HasRowid(pTab) ) cnt++;
+        for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
+        if( nIdx>mxIdx ) mxIdx = nIdx;
+      }
+      aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
+      if( aRoot==0 ) break;
+      for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+        Table *pTab = sqliteHashData(x);
+        Index *pIdx;
+        if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum;
         for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-          sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
-          VdbeComment((v, "%s", pIdx->zName));
-          cnt++;
+          aRoot[cnt++] = pIdx->tnum;
         }
       }
+      aRoot[cnt] = 0;
 
       /* Make sure sufficient number of registers have been allocated */
-      pParse->nMem = MAX( pParse->nMem, cnt+8 );
+      pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
 
       /* Do the b-tree integrity checks */
-      sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
+      sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
       sqlite3VdbeChangeP5(v, (u8)i);
       addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
       sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
@@ -109109,7 +111708,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
           sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
         }
-        pParse->nMem = MAX(pParse->nMem, 8+j);
+        assert( pParse->nMem>=8+j );
+        assert( sqlite3NoTempsInRange(pParse,1,7+j) );
         sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
         loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
         /* Verify that all NOT NULL columns really are NOT NULL */
@@ -109215,7 +111815,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       if( aOp ){
         aOp[0].p2 = -mxErr;
         aOp[2].p4type = P4_STATIC;
-        aOp[2].p4.z = "ok";
+        aOp[2].p4.z = (char *)"ok";
       }
     }
   }
@@ -109247,7 +111847,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
   */
   case PragTyp_ENCODING: {
     static const struct EncName {
-      char *zName;
+      const char *zName;
       u8 enc;
     } encnames[] = {
       { "UTF8",     SQLITE_UTF8        },
@@ -109301,7 +111901,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
   **   PRAGMA [schema.]user_version
   **   PRAGMA [schema.]user_version = <integer>
   **
-  **   PRAGMA [schema.]freelist_count = <integer>
+  **   PRAGMA [schema.]freelist_count
+  **
+  **   PRAGMA [schema.]data_version
   **
   **   PRAGMA [schema.]application_id
   **   PRAGMA [schema.]application_id = <integer>
@@ -109357,6 +111959,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       aOp[1].p3 = iCookie;
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
+      sqlite3VdbeReusable(v);
     }
   }
   break;
@@ -109378,6 +111981,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       sqlite3VdbeLoadString(v, 1, zOpt);
       sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
     }
+    sqlite3VdbeReusable(v);
   }
   break;
 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
@@ -109617,7 +112221,7 @@ static void corruptSchema(
     sqlite3DbFree(db, *pData->pzErrMsg);
     *pData->pzErrMsg = z;
   }
-  pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
+  pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
 }
 
 /*
@@ -109891,7 +112495,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
 #endif
   }
   if( db->mallocFailed ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
     sqlite3ResetAllSchemasOfConnection(db);
   }
   if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
@@ -110108,7 +112712,7 @@ static int sqlite3Prepare(
   /* Allocate the parsing context */
   pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
   if( pParse==0 ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
     goto end_prepare;
   }
   pParse->pReprepare = pReprepare;
@@ -110185,7 +112789,7 @@ static int sqlite3Prepare(
     schemaIsValid(pParse);
   }
   if( db->mallocFailed ){
-    pParse->rc = SQLITE_NOMEM;
+    pParse->rc = SQLITE_NOMEM_BKPT;
   }
   if( pzTail ){
     *pzTail = pParse->zTail;
@@ -110517,7 +113121,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
     sqlite3ExprListDelete(db, p->pOrderBy);
     sqlite3ExprDelete(db, p->pLimit);
     sqlite3ExprDelete(db, p->pOffset);
-    sqlite3WithDelete(db, p->pWith);
+    if( p->pWith ) sqlite3WithDelete(db, p->pWith);
     if( bFree ) sqlite3DbFree(db, p);
     p = pPrior;
     bFree = 1;
@@ -110548,7 +113152,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
   ExprList *pGroupBy,   /* the GROUP BY clause */
   Expr *pHaving,        /* the HAVING clause */
   ExprList *pOrderBy,   /* the ORDER BY clause */
-  u16 selFlags,         /* Flag parameters, such as SF_Distinct */
+  u32 selFlags,         /* Flag parameters, such as SF_Distinct */
   Expr *pLimit,         /* LIMIT value.  NULL means not used */
   Expr *pOffset         /* OFFSET value.  NULL means no offset */
 ){
@@ -110612,7 +113216,7 @@ SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
 ** Delete the given Select structure and all of its substructures.
 */
 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
-  clearSelect(db, p, 1);
+  if( p ) clearSelect(db, p, 1);
 }
 
 /*
@@ -111541,7 +114145,7 @@ static KeyInfo *keyInfoFromExprList(
 ** Name of the connection operator, used for error messages.
 */
 static const char *selectOpName(int id){
-  char *z;
+  const char *z;
   switch( id ){
     case TK_ALL:       z = "UNION ALL";   break;
     case TK_INTERSECT: z = "INTERSECT";   break;
@@ -111872,8 +114476,8 @@ static const char *columnTypeImpl(
           zType = "INTEGER";
           zOrigCol = "rowid";
         }else{
-          zType = pTab->aCol[iCol].zType;
           zOrigCol = pTab->aCol[iCol].zName;
+          zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
           estWidth = pTab->aCol[iCol].szEst;
         }
         zOrigTab = pTab->zName;
@@ -111885,7 +114489,7 @@ static const char *columnTypeImpl(
         if( iCol<0 ){
           zType = "INTEGER";
         }else{
-          zType = pTab->aCol[iCol].zType;
+          zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
           estWidth = pTab->aCol[iCol].szEst;
         }
 #endif
@@ -112000,7 +114604,7 @@ static void generateColumnNames(
       sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
     }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
       Table *pTab;
-      char *zCol;
+      const char *zCol;
       int iCol = p->iColumn;
       for(j=0; ALWAYS(j<pTabList->nSrc); j++){
         if( pTabList->a[j].iCursor==p->iTable ) break;
@@ -112093,7 +114697,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
         int iCol = pColExpr->iColumn;
         pTab = pColExpr->pTab;
         if( iCol<0 ) iCol = pTab->iPKey;
-        zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
+        zName = iCol>=0 ? pTab->aCol[iCol].zName : (char *)"rowid";
       }else if( pColExpr->op==TK_ID ){
         assert( !ExprHasProperty(pColExpr, EP_IntValue) );
         zName = pColExpr->u.zToken;
@@ -112131,7 +114735,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
     sqlite3DbFree(db, aCol);
     *paCol = 0;
     *pnCol = 0;
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   return SQLITE_OK;
 }
@@ -112147,7 +114751,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
 ** This routine requires that all identifiers in the SELECT
 ** statement be resolved.
 */
-static void selectAddColumnTypeAndCollation(
+SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
   Parse *pParse,        /* Parsing contexts */
   Table *pTab,          /* Add column type information to this table */
   Select *pSelect       /* SELECT used to determine types and collations */
@@ -112169,13 +114773,20 @@ static void selectAddColumnTypeAndCollation(
   sNC.pSrcList = pSelect->pSrc;
   a = pSelect->pEList->a;
   for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
+    const char *zType;
+    int n, m;
     p = a[i].pExpr;
-    if( pCol->zType==0 ){
-      pCol->zType = sqlite3DbStrDup(db, 
-                        columnType(&sNC, p,0,0,0, &pCol->szEst));
-    }
+    zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
     szAll += pCol->szEst;
     pCol->affinity = sqlite3ExprAffinity(p);
+    if( zType && (m = sqlite3Strlen30(zType))>0 ){
+      n = sqlite3Strlen30(pCol->zName);
+      pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
+      if( pCol->zName ){
+        memcpy(&pCol->zName[n+1], zType, m+1);
+        pCol->colFlags |= COLFLAG_HASTYPE;
+      }
+    }
     if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
     pColl = sqlite3ExprCollSeq(pParse, p);
     if( pColl && pCol->zColl==0 ){
@@ -112212,7 +114823,7 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
   pTab->zName = 0;
   pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
   sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
-  selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
+  sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
   pTab->iPKey = -1;
   if( db->mallocFailed ){
     sqlite3DeleteTable(db, pTab);
@@ -112225,20 +114836,20 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
 ** Get a VDBE for the given parser context.  Create a new one if necessary.
 ** If an error occurs, return NULL and leave a message in pParse.
 */
-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
-  Vdbe *v = pParse->pVdbe;
-  if( v==0 ){
-    v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
-    if( v ) sqlite3VdbeAddOp0(v, OP_Init);
-    if( pParse->pToplevel==0
-     && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
-    ){
-      pParse->okConstFactor = 1;
-    }
-
+static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
+  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
+  if( v ) sqlite3VdbeAddOp0(v, OP_Init);
+  if( pParse->pToplevel==0
+   && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
+  ){
+    pParse->okConstFactor = 1;
   }
   return v;
 }
+SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
+  Vdbe *v = pParse->pVdbe;
+  return v ? v : allocVdbe(pParse);
+}
 
 
 /*
@@ -112288,8 +114899,9 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
       VdbeComment((v, "LIMIT counter"));
       if( n==0 ){
         sqlite3VdbeGoto(v, iBreak);
-      }else if( n>=0 && p->nSelectRow>(u64)n ){
-        p->nSelectRow = n;
+      }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
+        p->nSelectRow = sqlite3LogEst((u64)n);
+        p->selFlags |= SF_FixedLimit;
       }
     }else{
       sqlite3ExprCode(pParse, p->pLimit, iLimit);
@@ -112667,7 +115279,6 @@ static int multiSelect(
   if( dest.eDest==SRT_EphemTab ){
     assert( p->pEList );
     sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
-    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
     dest.eDest = SRT_Table;
   }
 
@@ -112730,12 +115341,12 @@ static int multiSelect(
       testcase( rc!=SQLITE_OK );
       pDelete = p->pPrior;
       p->pPrior = pPrior;
-      p->nSelectRow += pPrior->nSelectRow;
+      p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
       if( pPrior->pLimit
        && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
-       && nLimit>0 && p->nSelectRow > (u64)nLimit 
+       && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
       ){
-        p->nSelectRow = nLimit;
+        p->nSelectRow = sqlite3LogEst((u64)nLimit);
       }
       if( addr ){
         sqlite3VdbeJumpHere(v, addr);
@@ -112807,7 +115418,9 @@ static int multiSelect(
       pDelete = p->pPrior;
       p->pPrior = pPrior;
       p->pOrderBy = 0;
-      if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
+      if( p->op==TK_UNION ){
+        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+      }
       sqlite3ExprDelete(db, p->pLimit);
       p->pLimit = pLimit;
       p->pOffset = pOffset;
@@ -112942,7 +115555,7 @@ static int multiSelect(
     nCol = p->pEList->nExpr;
     pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
     if( !pKeyInfo ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
       goto multi_select_end;
     }
     for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
@@ -113297,7 +115910,7 @@ static int multiSelectOrderBy(
       }
       if( j==nOrderBy ){
         Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
-        if( pNew==0 ) return SQLITE_NOMEM;
+        if( pNew==0 ) return SQLITE_NOMEM_BKPT;
         pNew->flags |= EP_IntValue;
         pNew->u.iValue = i;
         pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
@@ -113444,7 +116057,7 @@ static int multiSelectOrderBy(
     addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
                                      VdbeCoverage(v);
     sqlite3VdbeGoto(v, addrEofA);
-    p->nSelectRow += pPrior->nSelectRow;
+    p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
   }
 
   /* Generate a subroutine to run when the results from select B
@@ -114219,12 +116832,18 @@ static int pushDownWhereTerms(
 ){
   Expr *pNew;
   int nChng = 0;
+  Select *pX;           /* For looping over compound SELECTs in pSubq */
   if( pWhere==0 ) return 0;
-  if( (pSubq->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
-     return 0; /* restrictions (1) and (2) */
+  for(pX=pSubq; pX; pX=pX->pPrior){
+    if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
+      testcase( pX->selFlags & SF_Aggregate );
+      testcase( pX->selFlags & SF_Recursive );
+      testcase( pX!=pSubq );
+      return 0; /* restrictions (1) and (2) */
+    }
   }
   if( pSubq->pLimit!=0 ){
-     return 0; /* restriction (3) */
+    return 0; /* restriction (3) */
   }
   while( pWhere->op==TK_AND ){
     nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
@@ -114534,7 +117153,7 @@ static int withExpand(
     pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
     pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
     pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
-    if( db->mallocFailed ) return SQLITE_NOMEM;
+    if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
     assert( pFrom->pSelect );
 
     /* Check if this is a recursive CTE. */
@@ -114994,7 +117613,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
       Select *pSel = pFrom->pSelect;
       if( pSel ){
         while( pSel->pPrior ) pSel = pSel->pPrior;
-        selectAddColumnTypeAndCollation(pParse, pTab, pSel);
+        sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
       }
     }
   }
@@ -115414,10 +118033,24 @@ SQLITE_PRIVATE int sqlite3Select(
     }
 
     /* Generate code to implement the subquery
+    **
+    ** The subquery is implemented as a co-routine if all of these are true:
+    **   (1)  The subquery is guaranteed to be the outer loop (so that it
+    **        does not need to be computed more than once)
+    **   (2)  The ALL keyword after SELECT is omitted.  (Applications are
+    **        allowed to say "SELECT ALL" instead of just "SELECT" to disable
+    **        the use of co-routines.)
+    **   (3)  Co-routines are not disabled using sqlite3_test_control()
+    **        with SQLITE_TESTCTRL_OPTIMIZATIONS.
+    **
+    ** TODO: Are there other reasons beside (1) to use a co-routine
+    ** implementation?
     */
-    if( pTabList->nSrc==1
-     && (p->selFlags & SF_All)==0
-     && OptimizationEnabled(db, SQLITE_SubqCoroutine)
+    if( i==0
+     && (pTabList->nSrc==1
+            || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */
+     && (p->selFlags & SF_All)==0                                   /* (2) */
+     && OptimizationEnabled(db, SQLITE_SubqCoroutine)               /* (3) */
     ){
       /* Implement a co-routine that will return a single row of the result
       ** set on each invocation.
@@ -115430,7 +118063,7 @@ SQLITE_PRIVATE int sqlite3Select(
       sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
       explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
       sqlite3Select(pParse, pSub, &dest);
-      pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+      pItem->pTab->nRowLogEst = pSub->nSelectRow;
       pItem->fg.viaCoroutine = 1;
       pItem->regResult = dest.iSdst;
       sqlite3VdbeEndCoroutine(v, pItem->regReturn);
@@ -115461,7 +118094,7 @@ SQLITE_PRIVATE int sqlite3Select(
       sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
       explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
       sqlite3Select(pParse, pSub, &dest);
-      pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+      pItem->pTab->nRowLogEst = pSub->nSelectRow;
       if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
       retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
       VdbeComment((v, "end %s", pItem->pTab->zName));
@@ -115512,6 +118145,13 @@ SQLITE_PRIVATE int sqlite3Select(
     ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
     ** original setting of the SF_Distinct flag, not the current setting */
     assert( sDistinct.isTnct );
+
+#if SELECTTRACE_ENABLED
+    if( sqlite3SelectTrace & 0x400 ){
+      SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
+      sqlite3TreeViewSelect(0, p, 0);
+    }
+#endif
   }
 
   /* If there is an ORDER BY clause, then create an ephemeral index to
@@ -115544,7 +118184,7 @@ SQLITE_PRIVATE int sqlite3Select(
   /* Set the limiter.
   */
   iEnd = sqlite3VdbeMakeLabel(v);
-  p->nSelectRow = LARGEST_INT64;
+  p->nSelectRow = 320;  /* 4 billion rows */
   computeLimitRegisters(pParse, p, iEnd);
   if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
     sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
@@ -115568,10 +118208,12 @@ SQLITE_PRIVATE int sqlite3Select(
   if( !isAgg && pGroupBy==0 ){
     /* No aggregate functions and no GROUP BY clause */
     u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
+    assert( WHERE_USE_LIMIT==SF_FixedLimit );
+    wctrlFlags |= p->selFlags & SF_FixedLimit;
 
     /* Begin the database scan. */
     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
-                               p->pEList, wctrlFlags, 0);
+                               p->pEList, wctrlFlags, p->nSelectRow);
     if( pWInfo==0 ) goto select_end;
     if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
       p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
@@ -115631,9 +118273,11 @@ SQLITE_PRIVATE int sqlite3Select(
       for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
         pItem->u.x.iAlias = 0;
       }
-      if( p->nSelectRow>100 ) p->nSelectRow = 100;
+      assert( 66==sqlite3LogEst(100) );
+      if( p->nSelectRow>66 ) p->nSelectRow = 66;
     }else{
-      p->nSelectRow = 1;
+      assert( 0==sqlite3LogEst(1) );
+      p->nSelectRow = 0;
     }
 
     /* If there is both a GROUP BY and an ORDER BY clause and they are
@@ -116190,7 +118834,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
   return 0;
 
 malloc_failed:
-  p->rc = SQLITE_NOMEM;
+  p->rc = SQLITE_NOMEM_BKPT;
   return 1;
 }
 
@@ -116231,7 +118875,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
   res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
   if( res.azResult==0 ){
      db->errCode = SQLITE_NOMEM;
-     return SQLITE_NOMEM;
+     return SQLITE_NOMEM_BKPT;
   }
   res.azResult[0] = 0;
   rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
@@ -116260,7 +118904,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
     if( azNew==0 ){
       sqlite3_free_table(&res.azResult[1]);
       db->errCode = SQLITE_NOMEM;
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     res.azResult = azNew;
   }
@@ -117662,7 +120306,7 @@ SQLITE_PRIVATE void sqlite3Update(
   ** case, set all bits of the colUsed mask (to ensure that the virtual
   ** table implementation makes all columns available).
   */
-  pTabList->a[0].colUsed = IsVirtual(pTab) ? (Bitmask)-1 : 0;
+  pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0;
 
   hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
 
@@ -117746,7 +120390,8 @@ SQLITE_PRIVATE void sqlite3Update(
   if( HasRowid(pTab) ){
     sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
     pWInfo = sqlite3WhereBegin(
-        pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
+        pParse, pTabList, pWhere, 0, 0,
+            WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE, iIdxCur
     );
     if( pWInfo==0 ) goto update_cleanup;
     okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
@@ -117984,11 +120629,30 @@ SQLITE_PRIVATE void sqlite3Update(
       VdbeCoverageNeverTaken(v);
     }
     sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
-  
-    /* If changing the record number, delete the old record.  */
+
+    /* If changing the rowid value, or if there are foreign key constraints
+    ** to process, delete the old record. Otherwise, add a noop OP_Delete
+    ** to invoke the pre-update hook.
+    **
+    ** That (regNew==regnewRowid+1) is true is also important for the 
+    ** pre-update hook. If the caller invokes preupdate_new(), the returned
+    ** value is copied from memory cell (regNewRowid+1+iCol), where iCol
+    ** is the column index supplied by the user.
+    */
+    assert( regNew==regNewRowid+1 );
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+    sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
+        OPFLAG_ISUPDATE | ((hasFK || chngKey || pPk!=0) ? 0 : OPFLAG_ISNOOP),
+        regNewRowid
+    );
+    if( !pParse->nested ){
+      sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE);
+    }
+#else
     if( hasFK || chngKey || pPk!=0 ){
       sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
     }
+#endif
     if( bReplace || chngKey ){
       sqlite3VdbeJumpHere(v, addr1);
     }
@@ -118245,7 +120909,7 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
   sqlite3_stmt *pStmt;
   VVA_ONLY( int rc; )
   if( !zSql ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
     sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
@@ -118324,7 +120988,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   int rc = SQLITE_OK;     /* Return code from service routines */
   Btree *pMain;           /* The database being vacuumed */
   Btree *pTemp;           /* The temporary database we vacuum into */
-  char *zSql = 0;         /* SQL statements */
+  const char *zSql = 0;   /* SQL statements */
   int saved_flags;        /* Saved value of the db->flags */
   int saved_nChange;      /* Saved value of db->nChange */
   int saved_nTotalChange; /* Saved value of db->nTotalChange */
@@ -118426,7 +121090,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
    || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
    || NEVER(db->mallocFailed)
   ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
     goto end_of_vacuum;
   }
 
@@ -119090,19 +121754,19 @@ static int vtabCallConstructor(
 
   zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
   if( !zModuleName ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 
   pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
   if( !pVTable ){
     sqlite3DbFree(db, zModuleName);
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   pVTable->db = db;
   pVTable->pMod = pMod;
 
   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-  pTab->azModuleArg[1] = db->aDb[iDb].zName;
+  pTab->azModuleArg[1] = (char *)db->aDb[iDb].zName;
 
   /* Invoke the virtual table constructor */
   assert( &db->pVtabCtx );
@@ -119148,22 +121812,16 @@ static int vtabCallConstructor(
       pTab->pVTable = pVTable;
 
       for(iCol=0; iCol<pTab->nCol; iCol++){
-        char *zType = pTab->aCol[iCol].zType;
+        char *zType = (char *) sqlite3ColumnType(&pTab->aCol[iCol], 0);
         int nType;
         int i = 0;
-        if( !zType ){
-          pTab->tabFlags |= oooHidden;
-          continue;
-        }
         nType = sqlite3Strlen30(zType);
-        if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
-          for(i=0; i<nType; i++){
-            if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
-             && (zType[i+7]=='\0' || zType[i+7]==' ')
-            ){
-              i++;
-              break;
-            }
+        for(i=0; i<nType; i++){
+          if( 0==sqlite3StrNICmp("hidden", &zType[i], 6)
+           && (i==0 || zType[i-1]==' ')
+           && (zType[i+6]=='\0' || zType[i+6]==' ')
+          ){
+            break;
           }
         }
         if( i<nType ){
@@ -119239,7 +121897,7 @@ static int growVTrans(sqlite3 *db){
     int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
     aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
     if( !aVTrans ){
-      return SQLITE_NOMEM;
+      return SQLITE_NOMEM_BKPT;
     }
     memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
     db->aVTrans = aVTrans;
@@ -119331,7 +121989,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCre
 
   pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
   if( pParse==0 ){
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }else{
     pParse->declareVtab = 1;
     pParse->db = db;
@@ -119643,8 +122301,8 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
     return pDef;
   }
   *pNew = *pDef;
-  pNew->zName = (char *)&pNew[1];
-  memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
+  pNew->zName = (const char*)&pNew[1];
+  memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1);
   pNew->xSFunc = xSFunc;
   pNew->pUserData = pArg;
   pNew->funcFlags |= SQLITE_FUNC_EPHEM;
@@ -119891,7 +122549,7 @@ struct WhereLevel {
   int addrFirst;        /* First instruction of interior of the loop */
   int addrBody;         /* Beginning of the body of this loop */
 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
-  int iLikeRepCntr;     /* LIKE range processing counter register */
+  u32 iLikeRepCntr;     /* LIKE range processing counter register (times 2) */
   int addrLikeRep;      /* LIKE range processing address */
 #endif
   u8 iFrom;             /* Which entry in the FROM clause */
@@ -119950,7 +122608,7 @@ struct WhereLoop {
       u8 needFree;           /* True if sqlite3_free(idxStr) is needed */
       i8 isOrdered;          /* True if satisfies ORDER BY */
       u16 omitMask;          /* Terms that may be omitted */
-      char *idxStr;          /* Index identifier string */
+      const char *idxStr;    /* Index identifier string */
     } vtab;
   } u;
   u32 wsFlags;          /* WHERE_* flags describing the plan */
@@ -120229,10 +122887,11 @@ struct WhereInfo {
   Parse *pParse;            /* Parsing and code generating context */
   SrcList *pTabList;        /* List of tables in the join */
   ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
-  ExprList *pResultSet;     /* Result set. DISTINCT operates on these */
+  ExprList *pDistinctSet;   /* DISTINCT over all these values */
   WhereLoop *pLoops;        /* List of all WhereLoop objects */
   Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
   LogEst nRowOut;           /* Estimated number of output rows */
+  LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
   u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
   i8 nOBSat;                /* Number of ORDER BY terms satisfied by indices */
   u8 sorted;                /* True if really sorted (not just grouped) */
@@ -120312,6 +122971,14 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
 ** operators that are of interest to the query planner.  An
 ** OR-ed combination of these values can be used when searching for
 ** particular WhereTerms within a WhereClause.
+**
+** Value constraints:
+**     WO_EQ    == SQLITE_INDEX_CONSTRAINT_EQ
+**     WO_LT    == SQLITE_INDEX_CONSTRAINT_LT
+**     WO_LE    == SQLITE_INDEX_CONSTRAINT_LE
+**     WO_GT    == SQLITE_INDEX_CONSTRAINT_GT
+**     WO_GE    == SQLITE_INDEX_CONSTRAINT_GE
+**     WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH
 */
 #define WO_IN     0x0001
 #define WO_EQ     0x0002
@@ -120898,9 +123565,10 @@ static int codeAllEqualityTerms(
 
 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
 /*
-** If the most recently coded instruction is a constant range contraint
-** that originated from the LIKE optimization, then change the P3 to be
-** pLoop->iLikeRepCntr and set P5.
+** If the most recently coded instruction is a constant range constraint
+** (a string literal) that originated from the LIKE optimization, then 
+** set P3 and P5 on the OP_String opcode so that the string will be cast
+** to a BLOB at appropriate times.
 **
 ** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
 ** expression: "x>='ABC' AND x<'abd'".  But this requires that the range
@@ -120925,8 +123593,8 @@ static void whereLikeOptimizationStringFixup(
     assert( pOp!=0 );
     assert( pOp->opcode==OP_String8 
             || pTerm->pWC->pWInfo->pParse->db->mallocFailed );
-    pOp->p3 = pLevel->iLikeRepCntr;
-    pOp->p5 = 1;
+    pOp->p3 = (int)(pLevel->iLikeRepCntr>>1);  /* Register holding counter */
+    pOp->p5 = (u8)(pLevel->iLikeRepCntr&1);    /* ASC or DESC */
   }
 }
 #else
@@ -121212,6 +123880,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     int iReg;   /* P3 Value for OP_VFilter */
     int addrNotFound;
     int nConstraint = pLoop->nLTerm;
+    int iIn;    /* Counter for IN constraints */
 
     sqlite3ExprCachePush(pParse);
     iReg = sqlite3GetTempRange(pParse, nConstraint+2);
@@ -121219,7 +123888,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     for(j=0; j<nConstraint; j++){
       int iTarget = iReg+j+2;
       pTerm = pLoop->aLTerm[j];
-      if( pTerm==0 ) continue;
+      if( NEVER(pTerm==0) ) continue;
       if( pTerm->eOperator & WO_IN ){
         codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
         addrNotFound = pLevel->addrNxt;
@@ -121234,15 +123903,57 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
                       pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
     VdbeCoverage(v);
     pLoop->u.vtab.needFree = 0;
-    for(j=0; j<nConstraint && j<16; j++){
-      if( (pLoop->u.vtab.omitMask>>j)&1 ){
-        disableTerm(pLevel, pLoop->aLTerm[j]);
-      }
-    }
     pLevel->p1 = iCur;
     pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
     pLevel->p2 = sqlite3VdbeCurrentAddr(v);
-    sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
+    iIn = pLevel->u.in.nIn;
+    for(j=nConstraint-1; j>=0; j--){
+      pTerm = pLoop->aLTerm[j];
+      if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
+        disableTerm(pLevel, pTerm);
+      }else if( (pTerm->eOperator & WO_IN)!=0 ){
+        Expr *pCompare;  /* The comparison operator */
+        Expr *pRight;    /* RHS of the comparison */
+        VdbeOp *pOp;     /* Opcode to access the value of the IN constraint */
+
+        /* Reload the constraint value into reg[iReg+j+2].  The same value
+        ** was loaded into the same register prior to the OP_VFilter, but
+        ** the xFilter implementation might have changed the datatype or
+        ** encoding of the value in the register, so it *must* be reloaded. */
+        assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
+        if( !db->mallocFailed ){
+          assert( iIn>0 );
+          pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[--iIn].addrInTop);
+          assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
+          assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
+          assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
+          testcase( pOp->opcode==OP_Rowid );
+          sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
+        }
+
+        /* Generate code that will continue to the next row if 
+        ** the IN constraint is not satisfied */
+        pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0, 0);
+        assert( pCompare!=0 || db->mallocFailed );
+        if( pCompare ){
+          pCompare->pLeft = pTerm->pExpr->pLeft;
+          pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
+          if( pRight ){
+            pRight->iTable = iReg+j+2;
+            sqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0);
+          }
+          pCompare->pLeft = 0;
+          sqlite3ExprDelete(db, pCompare);
+        }
+      }
+    }
+    /* These registers need to be preserved in case there is an IN operator
+    ** loop.  So we could deallocate the registers here (and potentially
+    ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0.  But it seems
+    ** simpler and safer to simply not reuse the registers.
+    **
+    **    sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
+    */
     sqlite3ExprCachePop(pParse);
   }else
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -121470,14 +124181,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
       if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
         assert( pRangeStart!=0 );                     /* LIKE opt constraints */
         assert( pRangeStart->wtFlags & TERM_LIKEOPT );   /* occur in pairs */
-        pLevel->iLikeRepCntr = ++pParse->nMem;
-        testcase( bRev );
-        testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
-        sqlite3VdbeAddOp2(v, OP_Integer,
-                          bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC),
-                          pLevel->iLikeRepCntr);
+        pLevel->iLikeRepCntr = (u32)++pParse->nMem;
+        sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr);
         VdbeComment((v, "LIKE loop counter"));
         pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
+        /* iLikeRepCntr actually stores 2x the counter register number.  The
+        ** bottom bit indicates whether the search order is ASC or DESC. */
+        testcase( bRev );
+        testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
+        assert( (bRev & ~1)==0 );
+        pLevel->iLikeRepCntr <<=1;
+        pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
       }
 #endif
       if( pRangeStart==0
@@ -121550,16 +124264,22 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
       start_constraints = 1;
     }
     codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
-    op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
-    assert( op!=0 );
-    sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
-    VdbeCoverage(v);
-    VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
-    VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
-    VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
-    VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
-    VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
-    VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );
+    if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
+      /* The skip-scan logic inside the call to codeAllEqualityConstraints()
+      ** above has already left the cursor sitting on the correct row,
+      ** so no further seeking is needed */
+    }else{
+      op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+      assert( op!=0 );
+      sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+      VdbeCoverage(v);
+      VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
+      VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
+      VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
+      VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
+      VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
+      VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );
+    }
 
     /* Load the value for the inequality constraint at the end of the
     ** range (if any).
@@ -121609,7 +124329,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     if( omitTable ){
       /* pIdx is a covering index.  No need to access the main table. */
     }else if( HasRowid(pIdx->pTable) ){
-      if( pWInfo->eOnePass!=ONEPASS_OFF ){
+      if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)!=0 ){
         iRowidReg = ++pParse->nMem;
         sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
         sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
@@ -121805,7 +124525,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     wctrlFlags =  WHERE_OMIT_OPEN_CLOSE
                 | WHERE_FORCE_TABLE
                 | WHERE_ONETABLE_ONLY
-                | WHERE_NO_AUTOINDEX;
+                | WHERE_NO_AUTOINDEX
+                | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
     for(ii=0; ii<pOrWc->nTerm; ii++){
       WhereTerm *pOrTerm = &pOrWc->a[ii];
       if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
@@ -121985,11 +124706,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
       continue;
     }
     if( pTerm->wtFlags & TERM_LIKECOND ){
+      /* If the TERM_LIKECOND flag is set, that means that the range search
+      ** is sufficient to guarantee that the LIKE operator is true, so we
+      ** can skip the call to the like(A,B) function.  But this only works
+      ** for strings.  So do not skip the call to the function on the pass
+      ** that compares BLOBs. */
 #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
       continue;
 #else
-      assert( pLevel->iLikeRepCntr>0 );
-      skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
+      u32 x = pLevel->iLikeRepCntr;
+      assert( x>0 );
+      skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1));
       VdbeCoverage(v);
 #endif
     }
@@ -122596,6 +125323,7 @@ static void exprAnalyzeOrTerm(
   if( pOrInfo==0 ) return;
   pTerm->wtFlags |= TERM_ORINFO;
   pOrWc = &pOrInfo->wc;
+  memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic));
   sqlite3WhereClauseInit(pOrWc, pWInfo);
   sqlite3WhereSplit(pOrWc, pExpr, TK_OR);
   sqlite3WhereExprAnalyze(pSrc, pOrWc);
@@ -122622,6 +125350,7 @@ static void exprAnalyzeOrTerm(
         pOrTerm->wtFlags |= TERM_ANDINFO;
         pOrTerm->eOperator = WO_AND;
         pAndWC = &pAndInfo->wc;
+        memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
         sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
         sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
         sqlite3WhereExprAnalyze(pSrc, pAndWC);
@@ -123343,10 +126072,10 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
     return mask;
   }
   mask = sqlite3WhereExprUsage(pMaskSet, p->pRight);
-  mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
+  if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
   if( ExprHasProperty(p, EP_xIsSelect) ){
     mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
-  }else{
+  }else if( p->x.pList ){
     mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
   }
   return mask;
@@ -123456,8 +126185,8 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int);
 /*
 ** Return the estimated number of output rows from a WHERE clause
 */
-SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
-  return sqlite3LogEstToInt(pWInfo->nRowOut);
+SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+  return pWInfo->nRowOut;
 }
 
 /*
@@ -123686,7 +126415,10 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
 **
 ** The scanner will be searching the WHERE clause pWC.  It will look
 ** for terms of the form "X <op> <expr>" where X is column iColumn of table
-** iCur.  The <op> must be one of the operators described by opMask.
+** iCur.   Or if pIdx!=0 then X is column iColumn of index pIdx.  pIdx
+** must be one of the indexes of table iCur.
+**
+** The <op> must be one of the operators described by opMask.
 **
 ** If the search is for X and the WHERE clause contains terms of the
 ** form X=Y then this routine might also return terms of the form
@@ -123714,6 +126446,7 @@ static WhereTerm *whereScanInit(
     j = iColumn;
     iColumn = pIdx->aiColumn[j];
     if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
+    if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID;
   }
   if( pIdx && iColumn>=0 ){
     pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
@@ -123733,11 +126466,12 @@ static WhereTerm *whereScanInit(
 
 /*
 ** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
-** where X is a reference to the iColumn of table iCur and <op> is one of
-** the WO_xx operator codes specified by the op parameter.
-** Return a pointer to the term.  Return 0 if not found.
+** where X is a reference to the iColumn of table iCur or of index pIdx
+** if pIdx!=0 and <op> is one of the WO_xx operator codes specified by
+** the op parameter.  Return a pointer to the term.  Return 0 if not found.
 **
-** If pIdx!=0 then search for terms matching the iColumn-th column of pIdx
+** If pIdx!=0 then it must be one of the indexes of table iCur.  
+** Search for terms matching the iColumn-th column of pIdx
 ** rather than the iColumn-th column of table iCur.
 **
 ** The term returned might by Y=<expr> if there is another constraint in
@@ -124128,7 +126862,7 @@ static void constructAutomaticIndex(
   pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
   if( pIdx==0 ) goto end_auto_index_create;
   pLoop->u.btree.pIndex = pIdx;
-  pIdx->zName = "auto-index";
+  pIdx->zName = (char *)"auto-index";
   pIdx->pTable = pTable;
   n = 0;
   idxCols = 0;
@@ -124359,7 +127093,6 @@ static sqlite3_index_info *allocateIndexInfo(
 */
 static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
   sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
-  int i;
   int rc;
 
   TRACE_IDX_INPUTS(p);
@@ -124378,12 +127111,16 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
   sqlite3_free(pVtab->zErrMsg);
   pVtab->zErrMsg = 0;
 
+#if 0
+  /* This error is now caught by the caller.
+  ** Search for "xBestIndex malfunction" below */
   for(i=0; i<p->nConstraint; i++){
     if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
       sqlite3ErrorMsg(pParse, 
           "table %s: xBestIndex returned an invalid plan", pTab->zName);
     }
   }
+#endif
 
   return pParse->nErr;
 }
@@ -124986,7 +127723,8 @@ static int whereEqualScanEst(
   pBuilder->nRecValid = nEq;
 
   whereKeyStats(pParse, p, pRec, 0, a);
-  WHERETRACE(0x10,("equality scan regions: %d\n", (int)a[1]));
+  WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
+                   p->zName, nEq-1, (int)a[1]));
   *pnRow = a[1];
   
   return rc;
@@ -125071,11 +127809,12 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){
 */
 static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
   WhereInfo *pWInfo = pWC->pWInfo;
-  int nb = 1+(pWInfo->pTabList->nSrc+7)/8;
+  int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
   struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
   Table *pTab = pItem->pTab;
+  Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
   sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
-                     p->iTab, nb, p->maskSelf, nb, p->prereq);
+                     p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
   sqlite3DebugPrintf(" %12s",
                      pItem->zAlias ? pItem->zAlias : pTab->zName);
   if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
@@ -125133,7 +127872,7 @@ static void whereLoopInit(WhereLoop *p){
 static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
   if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){
     if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){
-      sqlite3_free(p->u.vtab.idxStr);
+      sqlite3_free((char *)p->u.vtab.idxStr);
       p->u.vtab.needFree = 0;
       p->u.vtab.idxStr = 0;
     }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
@@ -125161,7 +127900,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
   if( p->nLSlot>=n ) return SQLITE_OK;
   n = (n+7)&~7;
   paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
-  if( paNew==0 ) return SQLITE_NOMEM;
+  if( paNew==0 ) return SQLITE_NOMEM_BKPT;
   memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
   if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
   p->aLTerm = paNew;
@@ -125176,7 +127915,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
   whereLoopClearUnion(db, pTo);
   if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
     memset(&pTo->u, 0, sizeof(pTo->u));
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
   memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
@@ -125400,6 +128139,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
   WhereLoop **ppPrev, *p;
   WhereInfo *pWInfo = pBuilder->pWInfo;
   sqlite3 *db = pWInfo->pParse->db;
+  int rc;
 
   /* If pBuilder->pOrSet is defined, then only keep track of the costs
   ** and prereqs.
@@ -125458,7 +128198,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
   if( p==0 ){
     /* Allocate a new WhereLoop to add to the end of the list */
     *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop));
-    if( p==0 ) return SQLITE_NOMEM;
+    if( p==0 ) return SQLITE_NOMEM_BKPT;
     whereLoopInit(p);
     p->pNextLoop = 0;
   }else{
@@ -125482,14 +128222,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
       whereLoopDelete(db, pToDel);
     }
   }
-  whereLoopXfer(db, p, pTemplate);
+  rc = whereLoopXfer(db, p, pTemplate);
   if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
     Index *pIndex = p->u.btree.pIndex;
     if( pIndex && pIndex->tnum==0 ){
       p->u.btree.pIndex = 0;
     }
   }
-  return SQLITE_OK;
+  return rc;
 }
 
 /*
@@ -125614,14 +128354,12 @@ static int whereLoopAddBtreeIndex(
   WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
 
   pNew = pBuilder->pNew;
-  if( db->mallocFailed ) return SQLITE_NOMEM;
+  if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
 
   assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
   assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
   if( pNew->wsFlags & WHERE_BTM_LIMIT ){
     opMask = WO_LT|WO_LE;
-  }else if( /*pProbe->tnum<=0 ||*/ (pSrc->fg.jointype & JT_LEFT)!=0 ){
-    opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
   }else{
     opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
   }
@@ -125659,6 +128397,18 @@ static int whereLoopAddBtreeIndex(
     ** to mix with a lower range bound from some other source */
     if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
 
+    /* Do not allow IS constraints from the WHERE clause to be used by the
+    ** right table of a LEFT JOIN.  Only constraints in the ON clause are
+    ** allowed */
+    if( (pSrc->fg.jointype & JT_LEFT)!=0
+     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+     && (eOp & (WO_IS|WO_ISNULL))!=0
+    ){
+      testcase( eOp & WO_IS );
+      testcase( eOp & WO_ISNULL );
+      continue;
+    }
+
     pNew->wsFlags = saved_wsFlags;
     pNew->u.btree.nEq = saved_nEq;
     pNew->nLTerm = saved_nLTerm;
@@ -125978,7 +128728,7 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
 */
 static int whereLoopAddBtree(
   WhereLoopBuilder *pBuilder, /* WHERE clause information */
-  Bitmask mExtra              /* Extra prerequesites for using this table */
+  Bitmask mPrereq             /* Extra prerequesites for using this table */
 ){
   WhereInfo *pWInfo;          /* WHERE analysis context */
   Index *pProbe;              /* An index we are evaluating */
@@ -126078,7 +128828,7 @@ static int whereLoopAddBtree(
         pNew->nOut = 43;  assert( 43==sqlite3LogEst(20) );
         pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
         pNew->wsFlags = WHERE_AUTO_INDEX;
-        pNew->prereq = mExtra | pTerm->prereqRight;
+        pNew->prereq = mPrereq | pTerm->prereqRight;
         rc = whereLoopInsert(pBuilder, pNew);
       }
     }
@@ -126099,7 +128849,7 @@ static int whereLoopAddBtree(
     pNew->nLTerm = 0;
     pNew->iSortIdx = 0;
     pNew->rSetup = 0;
-    pNew->prereq = mExtra;
+    pNew->prereq = mPrereq;
     pNew->nOut = rSize;
     pNew->u.btree.pIndex = pProbe;
     b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
@@ -126172,12 +128922,160 @@ static int whereLoopAddBtree(
 }
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
+
+/*
+** Argument pIdxInfo is already populated with all constraints that may
+** be used by the virtual table identified by pBuilder->pNew->iTab. This
+** function marks a subset of those constraints usable, invokes the
+** xBestIndex method and adds the returned plan to pBuilder.
+**
+** A constraint is marked usable if:
+**
+**   * Argument mUsable indicates that its prerequisites are available, and
+**
+**   * It is not one of the operators specified in the mExclude mask passed
+**     as the fourth argument (which in practice is either WO_IN or 0).
+**
+** Argument mPrereq is a mask of tables that must be scanned before the
+** virtual table in question. These are added to the plans prerequisites
+** before it is added to pBuilder.
+**
+** Output parameter *pbIn is set to true if the plan added to pBuilder
+** uses one or more WO_IN terms, or false otherwise.
+*/
+static int whereLoopAddVirtualOne(
+  WhereLoopBuilder *pBuilder,
+  Bitmask mPrereq,                /* Mask of tables that must be used. */
+  Bitmask mUsable,                /* Mask of usable tables */
+  u16 mExclude,                   /* Exclude terms using these operators */
+  sqlite3_index_info *pIdxInfo,   /* Populated object for xBestIndex */
+  int *pbIn                       /* OUT: True if plan uses an IN(...) op */
+){
+  WhereClause *pWC = pBuilder->pWC;
+  struct sqlite3_index_constraint *pIdxCons;
+  struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
+  int i;
+  int mxTerm;
+  int rc = SQLITE_OK;
+  WhereLoop *pNew = pBuilder->pNew;
+  Parse *pParse = pBuilder->pWInfo->pParse;
+  struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab];
+  int nConstraint = pIdxInfo->nConstraint;
+
+  assert( (mUsable & mPrereq)==mPrereq );
+  *pbIn = 0;
+  pNew->prereq = mPrereq;
+
+  /* Set the usable flag on the subset of constraints identified by 
+  ** arguments mUsable and mExclude. */
+  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+  for(i=0; i<nConstraint; i++, pIdxCons++){
+    WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
+    pIdxCons->usable = 0;
+    if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight 
+     && (pTerm->eOperator & mExclude)==0
+    ){
+      pIdxCons->usable = 1;
+    }
+  }
+
+  /* Initialize the output fields of the sqlite3_index_info structure */
+  memset(pUsage, 0, sizeof(pUsage[0])*nConstraint);
+  assert( pIdxInfo->needToFreeIdxStr==0 );
+  pIdxInfo->idxStr = 0;
+  pIdxInfo->idxNum = 0;
+  pIdxInfo->orderByConsumed = 0;
+  pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
+  pIdxInfo->estimatedRows = 25;
+  pIdxInfo->idxFlags = 0;
+  pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
+
+  /* Invoke the virtual table xBestIndex() method */
+  rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
+  if( rc ) return rc;
+
+  mxTerm = -1;
+  assert( pNew->nLSlot>=nConstraint );
+  for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
+  pNew->u.vtab.omitMask = 0;
+  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+  for(i=0; i<nConstraint; i++, pIdxCons++){
+    int iTerm;
+    if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
+      WhereTerm *pTerm;
+      int j = pIdxCons->iTermOffset;
+      if( iTerm>=nConstraint
+       || j<0
+       || j>=pWC->nTerm
+       || pNew->aLTerm[iTerm]!=0
+       || pIdxCons->usable==0
+      ){
+        rc = SQLITE_ERROR;
+        sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
+        return rc;
+      }
+      testcase( iTerm==nConstraint-1 );
+      testcase( j==0 );
+      testcase( j==pWC->nTerm-1 );
+      pTerm = &pWC->a[j];
+      pNew->prereq |= pTerm->prereqRight;
+      assert( iTerm<pNew->nLSlot );
+      pNew->aLTerm[iTerm] = pTerm;
+      if( iTerm>mxTerm ) mxTerm = iTerm;
+      testcase( iTerm==15 );
+      testcase( iTerm==16 );
+      if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
+      if( (pTerm->eOperator & WO_IN)!=0 ){
+        /* A virtual table that is constrained by an IN clause may not
+        ** consume the ORDER BY clause because (1) the order of IN terms
+        ** is not necessarily related to the order of output terms and
+        ** (2) Multiple outputs from a single IN value will not merge
+        ** together.  */
+        pIdxInfo->orderByConsumed = 0;
+        pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
+        *pbIn = 1; assert( (mExclude & WO_IN)==0 );
+      }
+    }
+  }
+
+  pNew->nLTerm = mxTerm+1;
+  assert( pNew->nLTerm<=pNew->nLSlot );
+  pNew->u.vtab.idxNum = pIdxInfo->idxNum;
+  pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
+  pIdxInfo->needToFreeIdxStr = 0;
+  pNew->u.vtab.idxStr = pIdxInfo->idxStr;
+  pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
+      pIdxInfo->nOrderBy : 0);
+  pNew->rSetup = 0;
+  pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
+  pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
+
+  /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
+  ** that the scan will visit at most one row. Clear it otherwise. */
+  if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){
+    pNew->wsFlags |= WHERE_ONEROW;
+  }else{
+    pNew->wsFlags &= ~WHERE_ONEROW;
+  }
+  rc = whereLoopInsert(pBuilder, pNew);
+  if( pNew->u.vtab.needFree ){
+    sqlite3_free((char *)pNew->u.vtab.idxStr);
+    pNew->u.vtab.needFree = 0;
+  }
+  WHERETRACE(0xffff, ("  bIn=%d prereqIn=%04llx prereqOut=%04llx\n",
+                      *pbIn, (sqlite3_uint64)mPrereq,
+                      (sqlite3_uint64)(pNew->prereq & ~mPrereq)));
+
+  return rc;
+}
+
+
 /*
 ** Add all WhereLoop objects for a table of the join identified by
 ** pBuilder->pNew->iTab.  That table is guaranteed to be a virtual table.
 **
-** If there are no LEFT or CROSS JOIN joins in the query, both mExtra and
-** mUnusable are set to 0. Otherwise, mExtra is a mask of all FROM clause
+** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
+** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause
 ** entries that occur before the virtual table in the FROM clause and are
 ** separated from it by at least one LEFT or CROSS JOIN. Similarly, the
 ** mUnusable mask contains all FROM clause entries that occur after the
@@ -126188,188 +129086,122 @@ static int whereLoopAddBtree(
 **
 **   ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6;
 **
-** then mExtra corresponds to (t1, t2) and mUnusable to (t5, t6).
+** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6).
 **
-** All the tables in mExtra must be scanned before the current virtual 
+** All the tables in mPrereq must be scanned before the current virtual 
 ** table. So any terms for which all prerequisites are satisfied by 
-** mExtra may be specified as "usable" in all calls to xBestIndex. 
+** mPrereq may be specified as "usable" in all calls to xBestIndex. 
 ** Conversely, all tables in mUnusable must be scanned after the current
 ** virtual table, so any terms for which the prerequisites overlap with
 ** mUnusable should always be configured as "not-usable" for xBestIndex.
 */
 static int whereLoopAddVirtual(
   WhereLoopBuilder *pBuilder,  /* WHERE clause information */
-  Bitmask mExtra,              /* Tables that must be scanned before this one */
+  Bitmask mPrereq,             /* Tables that must be scanned before this one */
   Bitmask mUnusable            /* Tables that must be scanned after this one */
 ){
+  int rc = SQLITE_OK;          /* Return code */
   WhereInfo *pWInfo;           /* WHERE analysis context */
   Parse *pParse;               /* The parsing context */
   WhereClause *pWC;            /* The WHERE clause */
   struct SrcList_item *pSrc;   /* The FROM clause term to search */
-  Table *pTab;
-  sqlite3 *db;
-  sqlite3_index_info *pIdxInfo;
-  struct sqlite3_index_constraint *pIdxCons;
-  struct sqlite3_index_constraint_usage *pUsage;
-  WhereTerm *pTerm;
-  int i, j;
-  int iTerm, mxTerm;
-  int nConstraint;
-  int seenIn = 0;              /* True if an IN operator is seen */
-  int seenVar = 0;             /* True if a non-constant constraint is seen */
-  int iPhase;                  /* 0: const w/o IN, 1: const, 2: no IN,  2: IN */
+  sqlite3_index_info *p;       /* Object to pass to xBestIndex() */
+  int nConstraint;             /* Number of constraints in p */
+  int bIn;                     /* True if plan uses IN(...) operator */
   WhereLoop *pNew;
-  int rc = SQLITE_OK;
+  Bitmask mBest;               /* Tables used by best possible plan */
 
-  assert( (mExtra & mUnusable)==0 );
+  assert( (mPrereq & mUnusable)==0 );
   pWInfo = pBuilder->pWInfo;
   pParse = pWInfo->pParse;
-  db = pParse->db;
   pWC = pBuilder->pWC;
   pNew = pBuilder->pNew;
   pSrc = &pWInfo->pTabList->a[pNew->iTab];
-  pTab = pSrc->pTab;
-  assert( IsVirtual(pTab) );
-  pIdxInfo = allocateIndexInfo(pParse, pWC, mUnusable, pSrc,pBuilder->pOrderBy);
-  if( pIdxInfo==0 ) return SQLITE_NOMEM;
-  pNew->prereq = 0;
+  assert( IsVirtual(pSrc->pTab) );
+  p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy);
+  if( p==0 ) return SQLITE_NOMEM_BKPT;
   pNew->rSetup = 0;
   pNew->wsFlags = WHERE_VIRTUALTABLE;
   pNew->nLTerm = 0;
   pNew->u.vtab.needFree = 0;
-  pUsage = pIdxInfo->aConstraintUsage;
-  nConstraint = pIdxInfo->nConstraint;
-  if( whereLoopResize(db, pNew, nConstraint) ){
-    sqlite3DbFree(db, pIdxInfo);
-    return SQLITE_NOMEM;
-  }
-
-  for(iPhase=0; iPhase<=3; iPhase++){
-    if( !seenIn && (iPhase&1)!=0 ){
-      iPhase++;
-      if( iPhase>3 ) break;
-    }
-    if( !seenVar && iPhase>1 ) break;
-    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
-    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
-      j = pIdxCons->iTermOffset;
-      pTerm = &pWC->a[j];
-      switch( iPhase ){
-        case 0:    /* Constants without IN operator */
-          pIdxCons->usable = 0;
-          if( (pTerm->eOperator & WO_IN)!=0 ){
-            seenIn = 1;
-          }
-          if( (pTerm->prereqRight & ~mExtra)!=0 ){
-            seenVar = 1;
-          }else if( (pTerm->eOperator & WO_IN)==0 ){
-            pIdxCons->usable = 1;
-          }
-          break;
-        case 1:    /* Constants with IN operators */
-          assert( seenIn );
-          pIdxCons->usable = (pTerm->prereqRight & ~mExtra)==0;
-          break;
-        case 2:    /* Variables without IN */
-          assert( seenVar );
-          pIdxCons->usable = (pTerm->eOperator & WO_IN)==0;
-          break;
-        default:   /* Variables with IN */
-          assert( seenVar && seenIn );
-          pIdxCons->usable = 1;
-          break;
+  nConstraint = p->nConstraint;
+  if( whereLoopResize(pParse->db, pNew, nConstraint) ){
+    sqlite3DbFree(pParse->db, p);
+    return SQLITE_NOMEM_BKPT;
+  }
+
+  /* First call xBestIndex() with all constraints usable. */
+  WHERETRACE(0x40, ("  VirtualOne: all usable\n"));
+  rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, &bIn);
+
+  /* If the call to xBestIndex() with all terms enabled produced a plan
+  ** that does not require any source tables (IOW: a plan with mBest==0),
+  ** then there is no point in making any further calls to xBestIndex() 
+  ** since they will all return the same result (if the xBestIndex()
+  ** implementation is sane). */
+  if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
+    int seenZero = 0;             /* True if a plan with no prereqs seen */
+    int seenZeroNoIN = 0;         /* Plan with no prereqs and no IN(...) seen */
+    Bitmask mPrev = 0;
+    Bitmask mBestNoIn = 0;
+
+    /* If the plan produced by the earlier call uses an IN(...) term, call
+    ** xBestIndex again, this time with IN(...) terms disabled. */
+    if( bIn ){
+      WHERETRACE(0x40, ("  VirtualOne: all usable w/o IN\n"));
+      rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, WO_IN, p, &bIn);
+      assert( bIn==0 );
+      mBestNoIn = pNew->prereq & ~mPrereq;
+      if( mBestNoIn==0 ){
+        seenZero = 1;
+        seenZeroNoIN = 1;
+      }
+    }
+
+    /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) 
+    ** in the set of terms that apply to the current virtual table.  */
+    while( rc==SQLITE_OK ){
+      int i;
+      Bitmask mNext = ALLBITS;
+      assert( mNext>0 );
+      for(i=0; i<nConstraint; i++){
+        Bitmask mThis = (
+            pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq
+        );
+        if( mThis>mPrev && mThis<mNext ) mNext = mThis;
+      }
+      mPrev = mNext;
+      if( mNext==ALLBITS ) break;
+      if( mNext==mBest || mNext==mBestNoIn ) continue;
+      WHERETRACE(0x40, ("  VirtualOne: mPrev=%04llx mNext=%04llx\n",
+                       (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
+      rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mNext|mPrereq, 0, p, &bIn);
+      if( pNew->prereq==mPrereq ){
+        seenZero = 1;
+        if( bIn==0 ) seenZeroNoIN = 1;
       }
     }
-    memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
-    if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
-    pIdxInfo->idxStr = 0;
-    pIdxInfo->idxNum = 0;
-    pIdxInfo->needToFreeIdxStr = 0;
-    pIdxInfo->orderByConsumed = 0;
-    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
-    pIdxInfo->estimatedRows = 25;
-    pIdxInfo->idxFlags = 0;
-    pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
-    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
-    if( rc ) goto whereLoopAddVtab_exit;
-    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
-    pNew->prereq = mExtra;
-    mxTerm = -1;
-    assert( pNew->nLSlot>=nConstraint );
-    for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
-    pNew->u.vtab.omitMask = 0;
-    for(i=0; i<nConstraint; i++, pIdxCons++){
-      if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
-        j = pIdxCons->iTermOffset;
-        if( iTerm>=nConstraint
-         || j<0
-         || j>=pWC->nTerm
-         || pNew->aLTerm[iTerm]!=0
-        ){
-          rc = SQLITE_ERROR;
-          sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
-          goto whereLoopAddVtab_exit;
-        }
-        testcase( iTerm==nConstraint-1 );
-        testcase( j==0 );
-        testcase( j==pWC->nTerm-1 );
-        pTerm = &pWC->a[j];
-        pNew->prereq |= pTerm->prereqRight;
-        assert( iTerm<pNew->nLSlot );
-        pNew->aLTerm[iTerm] = pTerm;
-        if( iTerm>mxTerm ) mxTerm = iTerm;
-        testcase( iTerm==15 );
-        testcase( iTerm==16 );
-        if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
-        if( (pTerm->eOperator & WO_IN)!=0 ){
-          if( pUsage[i].omit==0 ){
-            /* Do not attempt to use an IN constraint if the virtual table
-            ** says that the equivalent EQ constraint cannot be safely omitted.
-            ** If we do attempt to use such a constraint, some rows might be
-            ** repeated in the output. */
-            break;
-          }
-          /* A virtual table that is constrained by an IN clause may not
-          ** consume the ORDER BY clause because (1) the order of IN terms
-          ** is not necessarily related to the order of output terms and
-          ** (2) Multiple outputs from a single IN value will not merge
-          ** together.  */
-          pIdxInfo->orderByConsumed = 0;
-          pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
-        }
-      }
-    }
-    if( i>=nConstraint ){
-      pNew->nLTerm = mxTerm+1;
-      assert( pNew->nLTerm<=pNew->nLSlot );
-      pNew->u.vtab.idxNum = pIdxInfo->idxNum;
-      pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
-      pIdxInfo->needToFreeIdxStr = 0;
-      pNew->u.vtab.idxStr = pIdxInfo->idxStr;
-      pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
-                                      pIdxInfo->nOrderBy : 0);
-      pNew->rSetup = 0;
-      pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
-      pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
 
-      /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
-      ** that the scan will visit at most one row. Clear it otherwise. */
-      if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){
-        pNew->wsFlags |= WHERE_ONEROW;
-      }else{
-        pNew->wsFlags &= ~WHERE_ONEROW;
-      }
-      whereLoopInsert(pBuilder, pNew);
-      if( pNew->u.vtab.needFree ){
-        sqlite3_free(pNew->u.vtab.idxStr);
-        pNew->u.vtab.needFree = 0;
-      }
+    /* If the calls to xBestIndex() in the above loop did not find a plan
+    ** that requires no source tables at all (i.e. one guaranteed to be
+    ** usable), make a call here with all source tables disabled */
+    if( rc==SQLITE_OK && seenZero==0 ){
+      WHERETRACE(0x40, ("  VirtualOne: all disabled\n"));
+      rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, 0, p, &bIn);
+      if( bIn==0 ) seenZeroNoIN = 1;
     }
-  }  
 
-whereLoopAddVtab_exit:
-  if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
-  sqlite3DbFree(db, pIdxInfo);
+    /* If the calls to xBestIndex() have so far failed to find a plan
+    ** that requires no source tables at all and does not use an IN(...)
+    ** operator, make a final call to obtain one here.  */
+    if( rc==SQLITE_OK && seenZeroNoIN==0 ){
+      WHERETRACE(0x40, ("  VirtualOne: all disabled and w/o IN\n"));
+      rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, WO_IN, p, &bIn);
+    }
+  }
+
+  if( p->needToFreeIdxStr ) sqlite3_free((char *)p->idxStr);
+  sqlite3DbFree(pParse->db, p);
   return rc;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -126380,7 +129212,7 @@ whereLoopAddVtab_exit:
 */
 static int whereLoopAddOr(
   WhereLoopBuilder *pBuilder, 
-  Bitmask mExtra
+  Bitmask mPrereq
   Bitmask mUnusable
 ){
   WhereInfo *pWInfo = pBuilder->pWInfo;
@@ -126441,14 +129273,14 @@ static int whereLoopAddOr(
 #endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
         if( IsVirtual(pItem->pTab) ){
-          rc = whereLoopAddVirtual(&sSubBuild, mExtra, mUnusable);
+          rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
         }else
 #endif
         {
-          rc = whereLoopAddBtree(&sSubBuild, mExtra);
+          rc = whereLoopAddBtree(&sSubBuild, mPrereq);
         }
         if( rc==SQLITE_OK ){
-          rc = whereLoopAddOr(&sSubBuild, mExtra, mUnusable);
+          rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
         }
         assert( rc==SQLITE_OK || sCur.n==0 );
         if( sCur.n==0 ){
@@ -126505,7 +129337,7 @@ static int whereLoopAddOr(
 */
 static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
   WhereInfo *pWInfo = pBuilder->pWInfo;
-  Bitmask mExtra = 0;
+  Bitmask mPrereq = 0;
   Bitmask mPrior = 0;
   int iTab;
   SrcList *pTabList = pWInfo->pTabList;
@@ -126526,7 +129358,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
     if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
       /* This condition is true when pItem is the FROM clause term on the
       ** right-hand-side of a LEFT or CROSS JOIN.  */
-      mExtra = mPrior;
+      mPrereq = mPrior;
     }
     priorJointype = pItem->fg.jointype;
     if( IsVirtual(pItem->pTab) ){
@@ -126536,12 +129368,12 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
           mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
         }
       }
-      rc = whereLoopAddVirtual(pBuilder, mExtra, mUnusable);
+      rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
     }else{
-      rc = whereLoopAddBtree(pBuilder, mExtra);
+      rc = whereLoopAddBtree(pBuilder, mPrereq);
     }
     if( rc==SQLITE_OK ){
-      rc = whereLoopAddOr(pBuilder, mExtra, mUnusable);
+      rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
     }
     mPrior |= pNew->maskSelf;
     if( rc || db->mallocFailed ) break;
@@ -126863,6 +129695,7 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
 ** order.
 */
 static LogEst whereSortingCost(
+  WhereInfo *pWInfo,
   LogEst nRow,
   int nOrderBy,
   int nSorted
@@ -126883,7 +129716,14 @@ static LogEst whereSortingCost(
   LogEst rScale, rSortCost;
   assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
   rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
-  rSortCost = nRow + estLog(nRow) + rScale + 16;
+  rSortCost = nRow + rScale + 16;
+
+  /* Multiple by log(M) where M is the number of output rows.
+  ** Use the LIMIT for M if it is smaller */
+  if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
+    nRow = pWInfo->iLimit;
+  }
+  rSortCost += estLog(nRow);
   return rSortCost;
 }
 
@@ -126946,7 +129786,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
   nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
   nSpace += sizeof(LogEst) * nOrderBy;
   pSpace = sqlite3DbMallocRawNN(db, nSpace);
-  if( pSpace==0 ) return SQLITE_NOMEM;
+  if( pSpace==0 ) return SQLITE_NOMEM_BKPT;
   aTo = (WherePath*)pSpace;
   aFrom = aTo+mxChoice;
   memset(aFrom, 0, sizeof(aFrom[0]));
@@ -127001,6 +129841,12 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
 
         if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
         if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){
+          /* Do not use an automatic index if the this loop is expected
+          ** to run less than 2 times. */
+          assert( 10==sqlite3LogEst(2) );
+          continue;
+        }
         /* At this point, pWLoop is a candidate to be the next loop. 
         ** Compute its cost */
         rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
@@ -127017,7 +129863,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
         if( isOrdered>=0 && isOrdered<nOrderBy ){
           if( aSortCost[isOrdered]==0 ){
             aSortCost[isOrdered] = whereSortingCost(
-                nRowEst, nOrderBy, isOrdered
+                pWInfo, nRowEst, nOrderBy, isOrdered
             );
           }
           rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
@@ -127193,9 +130039,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
    && nRowEst
   ){
     Bitmask notUsed;
-    int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
+    int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
                  WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
-    if( rc==pWInfo->pResultSet->nExpr ){
+    if( rc==pWInfo->pDistinctSet->nExpr ){
       pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
     }
   }
@@ -127253,7 +130099,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
   int j;
   Table *pTab;
   Index *pIdx;
-  
+
   pWInfo = pBuilder->pWInfo;
   if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0;
   assert( pWInfo->pTabList->nSrc>=1 );
@@ -127410,13 +130256,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
 ** used.
 */
 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
-  Parse *pParse,        /* The parser context */
-  SrcList *pTabList,    /* FROM clause: A list of all tables to be scanned */
-  Expr *pWhere,         /* The WHERE clause */
-  ExprList *pOrderBy,   /* An ORDER BY (or GROUP BY) clause, or NULL */
-  ExprList *pResultSet, /* Result set of the query */
-  u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
-  int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
+  Parse *pParse,          /* The parser context */
+  SrcList *pTabList,      /* FROM clause: A list of all tables to be scanned */
+  Expr *pWhere,           /* The WHERE clause */
+  ExprList *pOrderBy,     /* An ORDER BY (or GROUP BY) clause, or NULL */
+  ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */
+  u16 wctrlFlags,         /* The WHERE_* flags defined in sqliteInt.h */
+  int iAuxArg             /* If WHERE_ONETABLE_ONLY is set, index cursor number
+                          ** If WHERE_USE_LIMIT, then the limit amount */
 ){
   int nByteWInfo;            /* Num. bytes allocated for WhereInfo struct */
   int nTabList;              /* Number of elements in pTabList */
@@ -127437,6 +130284,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
      && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 
   ));
 
+  /* Only one of WHERE_ONETABLE_ONLY or WHERE_USE_LIMIT */
+  assert( (wctrlFlags & WHERE_ONETABLE_ONLY)==0
+            || (wctrlFlags & WHERE_USE_LIMIT)==0 );
+
   /* Variable initialization */
   db = pParse->db;
   memset(&sWLB, 0, sizeof(sWLB));
@@ -127487,9 +130338,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   pWInfo->pParse = pParse;
   pWInfo->pTabList = pTabList;
   pWInfo->pOrderBy = pOrderBy;
-  pWInfo->pResultSet = pResultSet;
+  pWInfo->pDistinctSet = pDistinctSet;
   pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
   pWInfo->wctrlFlags = wctrlFlags;
+  pWInfo->iLimit = iAuxArg;
   pWInfo->savedNQueryLoop = pParse->nQueryLoop;
   assert( pWInfo->eOnePass==ONEPASS_OFF );  /* ONEPASS defaults to OFF */
   pMaskSet = &pWInfo->sMaskSet;
@@ -127559,20 +130411,25 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   if( db->mallocFailed ) goto whereBeginError;
 
   if( wctrlFlags & WHERE_WANT_DISTINCT ){
-    if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
+    if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
       /* The DISTINCT marking is pointless.  Ignore it. */
       pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
     }else if( pOrderBy==0 ){
       /* Try to ORDER BY the result set to make distinct processing easier */
       pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
-      pWInfo->pOrderBy = pResultSet;
+      pWInfo->pOrderBy = pDistinctSet;
     }
   }
 
   /* Construct the WhereLoop objects */
-  WHERETRACE(0xffff,("*** Optimizer Start *** (wctrlFlags: 0x%x)\n",
-             wctrlFlags));
 #if defined(WHERETRACE_ENABLED)
+  if( sqlite3WhereTrace & 0xffff ){
+    sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
+    if( wctrlFlags & WHERE_USE_LIMIT ){
+      sqlite3DebugPrintf(", limit: %d", iAuxArg);
+    }
+    sqlite3DebugPrintf(")\n");
+  }
   if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
     int i;
     for(i=0; i<sWLB.pWC->nTerm; i++){
@@ -127606,7 +130463,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
     }
   }
   if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
-     pWInfo->revMask = (Bitmask)(-1);
+     pWInfo->revMask = ALLBITS;
   }
   if( pParse->nErr || NEVER(db->mallocFailed) ){
     goto whereBeginError;
@@ -127639,10 +130496,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
 #endif
   /* Attempt to omit tables from the join that do not effect the result */
   if( pWInfo->nLevel>=2
-   && pResultSet!=0
+   && pDistinctSet!=0
    && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
   ){
-    Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
+    Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
     if( sWLB.pOrderBy ){
       tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
     }
@@ -127755,8 +130612,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
       Index *pIx = pLoop->u.btree.pIndex;
       int iIndexCur;
       int op = OP_OpenRead;
-      /* iIdxCur is always set if to a positive value if ONEPASS is possible */
-      assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+      /* iAuxArg is always set if to a positive value if ONEPASS is possible */
+      assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
       if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
        && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0
       ){
@@ -127766,7 +130623,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
         op = 0;
       }else if( pWInfo->eOnePass!=ONEPASS_OFF ){
         Index *pJ = pTabItem->pTab->pIndex;
-        iIndexCur = iIdxCur;
+        iIndexCur = iAuxArg;
         assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
         while( ALWAYS(pJ) && pJ!=pIx ){
           iIndexCur++;
@@ -127774,8 +130631,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
         }
         op = OP_OpenWrite;
         pWInfo->aiCurOnePass[1] = iIndexCur;
-      }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
-        iIndexCur = iIdxCur;
+      }else if( iAuxArg && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
+        iIndexCur = iAuxArg;
         if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx;
       }else{
         iIndexCur = pParse->nTab++;
@@ -127908,13 +130765,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
     }
 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
     if( pLevel->addrLikeRep ){
-      int op;
-      if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
-        op = OP_DecrJumpZero;
-      }else{
-        op = OP_JumpZeroIncr;
-      }
-      sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
+      sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1),
+                        pLevel->addrLikeRep);
       VdbeCoverage(v);
     }
 #endif
@@ -128172,46 +131024,44 @@ static void disableLookaside(Parse *pParse){
   ** new Expr to populate pOut.  Set the span of pOut to be the identifier
   ** that created the expression.
   */
-  static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
-    pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
-    pOut->zStart = pValue->z;
-    pOut->zEnd = &pValue->z[pValue->n];
+  static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
+    pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, &t);
+    pOut->zStart = t.z;
+    pOut->zEnd = &t.z[t.n];
   }
 
   /* This routine constructs a binary expression node out of two ExprSpan
   ** objects and uses the result to populate a new ExprSpan object.
   */
   static void spanBinaryExpr(
-    ExprSpan *pOut,     /* Write the result here */
     Parse *pParse,      /* The parsing context.  Errors accumulate here */
     int op,             /* The binary operation */
-    ExprSpan *pLeft,    /* The left operand */
+    ExprSpan *pLeft,    /* The left operand, and output */
     ExprSpan *pRight    /* The right operand */
   ){
-    pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
-    pOut->zStart = pLeft->zStart;
-    pOut->zEnd = pRight->zEnd;
+    pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
+    pLeft->zEnd = pRight->zEnd;
   }
 
   /* If doNot is true, then add a TK_NOT Expr-node wrapper around the
   ** outside of *ppExpr.
   */
-  static void exprNot(Parse *pParse, int doNot, Expr **ppExpr){
-    if( doNot ) *ppExpr = sqlite3PExpr(pParse, TK_NOT, *ppExpr, 0, 0);
+  static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
+    if( doNot ){
+      pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0);
+    }
   }
 
   /* Construct an expression node for a unary postfix operator
   */
   static void spanUnaryPostfix(
-    ExprSpan *pOut,        /* Write the new expression node here */
     Parse *pParse,         /* Parsing context to record errors */
     int op,                /* The operator */
-    ExprSpan *pOperand,    /* The operand */
+    ExprSpan *pOperand,    /* The operand, and output */
     Token *pPostOp         /* The operand token for setting the span */
   ){
-    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
-    pOut->zStart = pOperand->zStart;
-    pOut->zEnd = &pPostOp->z[pPostOp->n];
+    pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+    pOperand->zEnd = &pPostOp->z[pPostOp->n];
   }                           
 
   /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
@@ -128234,8 +131084,8 @@ static void disableLookaside(Parse *pParse){
     ExprSpan *pOperand,    /* The operand */
     Token *pPreOp         /* The operand token for setting the span */
   ){
-    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
     pOut->zStart = pPreOp->z;
+    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
     pOut->zEnd = pOperand->zEnd;
   }
 
@@ -128320,26 +131170,26 @@ static void disableLookaside(Parse *pParse){
 #endif
 /************* Begin control #defines *****************************************/
 #define YYCODETYPE unsigned char
-#define YYNOCODE 253
+#define YYNOCODE 251
 #define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 70
+#define YYWILDCARD 96
 #define sqlite3ParserTOKENTYPE Token
 typedef union {
   int yyinit;
   sqlite3ParserTOKENTYPE yy0;
-  int yy4;
-  struct TrigEvent yy90;
-  ExprSpan yy118;
-  TriggerStep* yy203;
-  struct {int value; int mask;} yy215;
-  SrcList* yy259;
-  struct LimitVal yy292;
-  Expr* yy314;
-  ExprList* yy322;
-  struct LikeOp yy342;
-  IdList* yy384;
-  Select* yy387;
-  With* yy451;
+  struct LimitVal yy64;
+  Expr* yy122;
+  Select* yy159;
+  IdList* yy180;
+  struct {int value; int mask;} yy207;
+  struct LikeOp yy318;
+  TriggerStep* yy327;
+  With* yy331;
+  ExprSpan yy342;
+  SrcList* yy347;
+  int yy392;
+  struct TrigEvent yy410;
+  ExprList* yy442;
 } YYMINORTYPE;
 #ifndef YYSTACKDEPTH
 #define YYSTACKDEPTH 100
@@ -128349,22 +131199,18 @@ typedef union {
 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
 #define YYFALLBACK 1
-#define YYNSTATE             440
-#define YYNRULE              328
-#define YY_MAX_SHIFT         439
+#define YYNSTATE             444
+#define YYNRULE              326
+#define YY_MAX_SHIFT         443
 #define YY_MIN_SHIFTREDUCE   653
-#define YY_MAX_SHIFTREDUCE   980
-#define YY_MIN_REDUCE        981
-#define YY_MAX_REDUCE        1308
-#define YY_ERROR_ACTION      1309
-#define YY_ACCEPT_ACTION     1310
-#define YY_NO_ACTION         1311
+#define YY_MAX_SHIFTREDUCE   978
+#define YY_MIN_REDUCE        979
+#define YY_MAX_REDUCE        1304
+#define YY_ERROR_ACTION      1305
+#define YY_ACCEPT_ACTION     1306
+#define YY_NO_ACTION         1307
 /************* End control #defines *******************************************/
 
-/* The yyzerominor constant is used to initialize instances of
-** YYMINORTYPE objects to zero. */
-static const YYMINORTYPE yyzerominor = { 0 };
-
 /* Define the yytestcase() macro to be a no-op if is not already defined
 ** otherwise.
 **
@@ -128430,446 +131276,448 @@ static const YYMINORTYPE yyzerominor = { 0 };
 **  yy_default[]       Default action for each state.
 **
 *********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (1507)
+#define YY_ACTTAB_COUNT (1504)
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   315, 1310,  145,  655,    2,  192,  656,  342,  784,   92,
- /*    10 */    92,   92,   92,   85,   90,   90,   90,   90,   89,   89,
- /*    20 */    88,   88,   88,   87,  339,   88,   88,   88,   87,  339,
- /*    30 */   331,  860,  860,   92,   92,   92,   92,  701,   90,   90,
- /*    40 */    90,   90,   89,   89,   88,   88,   88,   87,  339,   76,
- /*    50 */   811,   74,   93,   94,   84,  872,  875,  864,  864,   91,
- /*    60 */    91,   92,   92,   92,   92,  339,   90,   90,   90,   90,
- /*    70 */    89,   89,   88,   88,   88,   87,  339,  315,  784,   90,
- /*    80 */    90,   90,   90,   89,   89,   88,   88,   88,   87,  339,
- /*    90 */   360,  812,  780,  705,  693,  693,   86,   83,  166,  261,
- /*   100 */   813,  719,  434,   86,   83,  166,  328,  701,  860,  860,
- /*   110 */   201,  158,  280,  391,  275,  390,  188,  693,  693,  832,
- /*   120 */    86,   83,  166,  273,  837,   49,  123,   87,  339,   93,
- /*   130 */    94,   84,  872,  875,  864,  864,   91,   91,   92,   92,
- /*   140 */    92,   92,  239,   90,   90,   90,   90,   89,   89,   88,
- /*   150 */    88,   88,   87,  339,  315,  767,  337,  336,  216,  412,
- /*   160 */   398,   69,  231,  397,  694,  695,  400,  914,  255,  358,
- /*   170 */   254,  292,  319,  434,  912,  434,  913,   89,   89,   88,
- /*   180 */    88,   88,   87,  339,  395,  860,  860,  694,  695,  183,
- /*   190 */    95,  123,  388,  385,  384,  837,   31,  837,   49,  916,
- /*   200 */   916,  755,  756,  383,  123,  315,   93,   94,   84,  872,
- /*   210 */   875,  864,  864,   91,   91,   92,   92,   92,   92,  114,
- /*   220 */    90,   90,   90,   90,   89,   89,   88,   88,   88,   87,
- /*   230 */   339,  434,  412,  403,  439,  661,  860,  860,  350,   57,
- /*   240 */   232,  832,  109,  708,  370,  693,  693,  367,  829,  764,
- /*   250 */    97,  753,  756,  837,   49,  712,  712,   93,   94,   84,
- /*   260 */   872,  875,  864,  864,   91,   91,   92,   92,   92,   92,
- /*   270 */   427,   90,   90,   90,   90,   89,   89,   88,   88,   88,
- /*   280 */    87,  339,  315,  114,   22,  365,  692,   58,  412,  394,
- /*   290 */   255,  353,  242,  213,  766,  693,  693,  851,  689,  115,
- /*   300 */   365,  231,  397,  693,  693,  400,  183,  693,  693,  388,
- /*   310 */   385,  384,  365,  860,  860,  694,  695,  160,  159,  223,
- /*   320 */   383,  742,   25,  810,  711,  845,  143,  693,  693,  839,
- /*   330 */   396,  343,  770,  770,   93,   94,   84,  872,  875,  864,
- /*   340 */   864,   91,   91,   92,   92,   92,   92,  918,   90,   90,
- /*   350 */    90,   90,   89,   89,   88,   88,   88,   87,  339,  315,
- /*   360 */   844,  844,  844,  270,  261,  694,  695,  782,  710,   86,
- /*   370 */    83,  166,  219,  694,  695,  741,    1,  694,  695,  693,
- /*   380 */   693,  693,  693,  434,   86,   83,  166,  253,  692,  941,
- /*   390 */   860,  860,  431,  703,  704,  832,  302,  694,  695,  221,
- /*   400 */   690,  115,  123,  948,  799,  837,   48,  346,  309,  974,
- /*   410 */   851,   93,   94,   84,  872,  875,  864,  864,   91,   91,
- /*   420 */    92,   92,   92,   92,  114,   90,   90,   90,   90,   89,
- /*   430 */    89,   88,   88,   88,   87,  339,  315,  944,  845,  683,
- /*   440 */   717,  433,  839,  434,  255,  358,  254,  359,  292,  694,
- /*   450 */   695,  694,  695,  289,  945,  344,  975,  291,  210,   23,
- /*   460 */   174,  797,  836,  434,  357,  837,   10,  860,  860,   24,
- /*   470 */   946,  151,  757,  844,  844,  844,  798,  972, 1294,  325,
- /*   480 */   402, 1294,  360,  356,  758,  837,   49,  939,   93,   94,
- /*   490 */    84,  872,  875,  864,  864,   91,   91,   92,   92,   92,
- /*   500 */    92,  434,   90,   90,   90,   90,   89,   89,   88,   88,
- /*   510 */    88,   87,  339,  315,  380,  114,  911,  709,  434,  911,
- /*   520 */   332,  894,  114,  837,   10,  970,  434,  861,  861,  324,
- /*   530 */   189,  163,  836,  165,  434,  910,  348,  327,  910,  908,
- /*   540 */   837,   10,  969,  310,  860,  860,  187,  423,  837,   10,
- /*   550 */   220,  873,  876,  836,  222,  407,  837,   49, 1223,  797,
- /*   560 */    68,  941,  410,  249,   66,   93,   94,   84,  872,  875,
- /*   570 */   864,  864,   91,   91,   92,   92,   92,   92,  865,   90,
- /*   580 */    90,   90,   90,   89,   89,   88,   88,   88,   87,  339,
- /*   590 */   315,  408,  213,  766,  838,  349,  114,  944,  906,  372,
- /*   600 */   731,    5,  320,  192,  400,  776,  784,  273,  230,  246,
- /*   610 */   775,  248,  401,  164,  945,  389,  123,  351,   55,  359,
- /*   620 */   333,  860,  860,  732,  337,  336,  692,  972, 1295,  728,
- /*   630 */   946, 1295,  417,  214,  837,    9,  366,  290,  959,  115,
- /*   640 */   722,  315,   93,   94,   84,  872,  875,  864,  864,   91,
- /*   650 */    91,   92,   92,   92,   92,  434,   90,   90,   90,   90,
- /*   660 */    89,   89,   88,   88,   88,   87,  339,  916,  916, 1304,
- /*   670 */  1304,  762,  860,  860,  329,  970,  784,  837,   35,  751,
- /*   680 */   724,  338,  703,  704,  981,  656,  342,  247,  749,  924,
- /*   690 */   924,  373,  187,   93,   94,   84,  872,  875,  864,  864,
- /*   700 */    91,   91,   92,   92,   92,   92,  114,   90,   90,   90,
- /*   710 */    90,   89,   89,   88,   88,   88,   87,  339,  315,  434,
- /*   720 */   958,  434,  112,  314,  434,  697,  321,  702,  404,  434,
- /*   730 */   797,  363,  434, 1021,  434,  192,  434,  405,  784,  434,
- /*   740 */   364,  837,   36,  837,   12,  434,  837,   27,  320,  860,
- /*   750 */   860,  837,   37,   20,  837,   38,  837,   39,  837,   28,
- /*   760 */    72,  837,   29,  667,  668,  669,  268,  837,   40,  234,
- /*   770 */    93,   94,   84,  872,  875,  864,  864,   91,   91,   92,
- /*   780 */    92,   92,   92,  434,   90,   90,   90,   90,   89,   89,
- /*   790 */    88,   88,   88,   87,  339,  315,  434,  702,  434,  921,
- /*   800 */   147,  434,  165,  920,  279,  837,   41,  434,  784,  434,
- /*   810 */    21,  434,  263,  434,  266,  278,  434,  371,  837,   42,
- /*   820 */   837,   11,  434,  837,   43,  235,  860,  860,  797,  837,
- /*   830 */    99,  837,   44,  837,   45,  837,   32,   75,  837,   46,
- /*   840 */   309,  971,  261,  261,  837,   47,  315,   93,   94,   84,
- /*   850 */   872,  875,  864,  864,   91,   91,   92,   92,   92,   92,
- /*   860 */   434,   90,   90,   90,   90,   89,   89,   88,   88,   88,
- /*   870 */    87,  339,  434,  186,  185,  184,  238,  860,  860,  654,
- /*   880 */     2, 1068,  837,   33,  743,  217,  218,  261,  975,  261,
- /*   890 */   430,  321,  261,  778,  837,  117,  261,  315,   93,   94,
- /*   900 */    84,  872,  875,  864,  864,   91,   91,   92,   92,   92,
- /*   910 */    92,  434,   90,   90,   90,   90,   89,   89,   88,   88,
- /*   920 */    88,   87,  339,  434,  322,  124,  212,  163,  860,  860,
- /*   930 */   947,  904,  902,  837,  118,  763,  730,  729,  261,  759,
- /*   940 */   293,  293,  737,  738,  965,  837,  119,  686,  315,   93,
- /*   950 */    82,   84,  872,  875,  864,  864,   91,   91,   92,   92,
- /*   960 */    92,   92,  434,   90,   90,   90,   90,   89,   89,   88,
- /*   970 */    88,   88,   87,  339,  434,  720,  250,  326,  335,  860,
- /*   980 */   860,  260,  114,  361,  837,   53,  812,  917,  917,  936,
- /*   990 */   156,  420,  424,  428,  934,  813,  837,   34,  368,  315,
- /*  1000 */   257,   94,   84,  872,  875,  864,  864,   91,   91,   92,
- /*  1010 */    92,   92,   92,  434,   90,   90,   90,   90,   89,   89,
- /*  1020 */    88,   88,   88,   87,  339,  434,  114,  114,  114,  964,
- /*  1030 */   860,  860,  311,  262,  834,  837,  100,  191,  256,  381,
- /*  1040 */   271,   68,  197,   68,  265,  720,  773,  837,   50,   71,
- /*  1050 */   915,  915,  267,   84,  872,  875,  864,  864,   91,   91,
- /*  1060 */    92,   92,   92,   92,  434,   90,   90,   90,   90,   89,
- /*  1070 */    89,   88,   88,   88,   87,  339,   80,  429,  806,    3,
- /*  1080 */  1218,  191,  434,  269,  340,  340,  837,  101,  745,   80,
- /*  1090 */   429,  901,    3,  727,  726,  432,  725,  340,  340,  434,
- /*  1100 */   897,  274,  434,  197,  837,  102,  434,  804,  432,  434,
- /*  1110 */   699,  434,  847,  111,  418,  434,  788,  413,  434,  835,
- /*  1120 */   434,  837,   98,  123,  837,  116,  851,  418,  837,   49,
- /*  1130 */   783,  837,  113,  837,  106,  226,  123,  837,  105,  851,
- /*  1140 */   837,  103,  837,  104,  795,  415,   77,   78,  294,  416,
- /*  1150 */   434,  295,  114,   79,  436,  435,  393,  434,  839,   77,
- /*  1160 */    78,  901,  843,  412,  414,  434,   79,  436,  435,  376,
- /*  1170 */   707,  839,  837,   52,  434,   80,  429,  434,    3,  837,
- /*  1180 */    54,  776,  847,  340,  340,  688,  775,  837,   51,  844,
- /*  1190 */   844,  844,  846,   19,  432,  676,  837,   26,  675,  837,
- /*  1200 */    30,  677,  844,  844,  844,  846,   19,  207,  665,  282,
- /*  1210 */   308,  148,  284,  418,  286,  252,  362,  241,  386,    6,
- /*  1220 */   352,  161,  277,   80,  429,  851,    3,  938,  899,  724,
- /*  1230 */   898,  340,  340,  300,  157,  419,  245,  288,  678,  962,
- /*  1240 */   194,  957,  432,  955,  952,   77,   78,  781,  323,   56,
- /*  1250 */    59,  135,   79,  436,  435,   96,  411,  839,  146,  826,
- /*  1260 */   240,  418,  121,  128,   66,  823,  244,  243,  354,  130,
- /*  1270 */   107,  355,  131,  851,  132,  133,  940,   70,  429,  379,
- /*  1280 */     3,  173,  138,  831,  149,  340,  340,  369,  844,  844,
- /*  1290 */   844,  846,   19,   77,   78,  178,  432,  893,   62,  375,
- /*  1300 */    79,  436,  435,  919,  259,  839,  796,  208,  179,  144,
- /*  1310 */   377,  264,  180,  392,  679,  418,  181,  312,  748,  747,
- /*  1320 */   746,  330,  716,  735,  313,  722,  406,  851,  792,  715,
- /*  1330 */    65,  281,  283,  276,  793,  791,  844,  844,  844,  846,
- /*  1340 */    19,  714,  713,  734,  285,  193,  287,   77,   78,  880,
- /*  1350 */   790,   73,  227,  422,   79,  436,  435,  334,  426,  839,
- /*  1360 */   215,   67,  409,  228,  298,  307,  306,  305,  204,  303,
- /*  1370 */   229,  771,  680,  296,  297,  299,  202,  685,    7,  437,
- /*  1380 */   673,  203,  206,  205,  660,  438,  317,  168,  671,  237,
- /*  1390 */   844,  844,  844,  846,   19,  670,  662,  110,  236,  318,
- /*  1400 */   125,  224,  341,  120,  155,  233,  167,  345,  108,  909,
- /*  1410 */   907,  170,  830,  126,  127,  760,  129,  251,  171,  172,
- /*  1420 */   932,  123,  169,  134,   60,   61,  136,  137,  937,  175,
- /*  1430 */   176,  931,    8,   13,  177,  922,  258,  139,  191,  928,
- /*  1440 */   374,  140,  150,  682,  378,  278,  182,  382,  141,  122,
- /*  1450 */    63,   14,  733,  769,  272,   15,  387,   64,  225,  850,
- /*  1460 */   849,  878,   16,  882,  774,    4,  162,  209,  399,  316,
- /*  1470 */   211,  142,  800,  805,   71,  190,   68,  879,  877,  943,
- /*  1480 */   199,  942,   17,  195,  196,  421,  979,   18,  152,  153,
- /*  1490 */   198,  980,  154,  425,  881,  848,  347,  700,   81,  200,
- /*  1500 */   301, 1023,  304,  657,  983,  983, 1022,
+ /*     0 */   319,  814,  343,  808,    5,  194,  194,  802,   92,   93,
+ /*    10 */    83,  823,  823,  835,  838,  827,  827,   90,   90,   91,
+ /*    20 */    91,   91,   91,  294,   89,   89,   89,   89,   88,   88,
+ /*    30 */    87,   87,   87,   86,  343,  319,  956,  956,  807,  807,
+ /*    40 */   807,  926,  346,   92,   93,   83,  823,  823,  835,  838,
+ /*    50 */   827,  827,   90,   90,   91,   91,   91,   91,  123,   89,
+ /*    60 */    89,   89,   89,   88,   88,   87,   87,   87,   86,  343,
+ /*    70 */    88,   88,   87,   87,   87,   86,  343,  776,  956,  956,
+ /*    80 */   319,   87,   87,   87,   86,  343,  777,   68,   92,   93,
+ /*    90 */    83,  823,  823,  835,  838,  827,  827,   90,   90,   91,
+ /*   100 */    91,   91,   91,  438,   89,   89,   89,   89,   88,   88,
+ /*   110 */    87,   87,   87,   86,  343, 1306,  146,  925,    2,  319,
+ /*   120 */   431,   24,  683,  957,   48,   86,  343,   92,   93,   83,
+ /*   130 */   823,  823,  835,  838,  827,  827,   90,   90,   91,   91,
+ /*   140 */    91,   91,   94,   89,   89,   89,   89,   88,   88,   87,
+ /*   150 */    87,   87,   86,  343,  937,  937,  319,  263,  416,  402,
+ /*   160 */   400,   57,  737,  737,   92,   93,   83,  823,  823,  835,
+ /*   170 */   838,  827,  827,   90,   90,   91,   91,   91,   91,   56,
+ /*   180 */    89,   89,   89,   89,   88,   88,   87,   87,   87,   86,
+ /*   190 */   343,  319, 1249,  926,  346,  272,  938,  939,  241,   92,
+ /*   200 */    93,   83,  823,  823,  835,  838,  827,  827,   90,   90,
+ /*   210 */    91,   91,   91,   91,  295,   89,   89,   89,   89,   88,
+ /*   220 */    88,   87,   87,   87,   86,  343,  319,  917, 1299,  686,
+ /*   230 */   691, 1299,  233,  401,   92,   93,   83,  823,  823,  835,
+ /*   240 */   838,  827,  827,   90,   90,   91,   91,   91,   91,  330,
+ /*   250 */    89,   89,   89,   89,   88,   88,   87,   87,   87,   86,
+ /*   260 */   343,  319,   85,   82,  168,  684,  435,  942,  943,   92,
+ /*   270 */    93,   83,  823,  823,  835,  838,  827,  827,   90,   90,
+ /*   280 */    91,   91,   91,   91,  295,   89,   89,   89,   89,   88,
+ /*   290 */    88,   87,   87,   87,   86,  343,  319,  323,  917, 1300,
+ /*   300 */   801,  915, 1300,  685,   92,   93,   83,  823,  823,  835,
+ /*   310 */   838,  827,  827,   90,   90,   91,   91,   91,   91,  339,
+ /*   320 */    89,   89,   89,   89,   88,   88,   87,   87,   87,   86,
+ /*   330 */   343,  319,  880,  880,  377,   85,   82,  168,  948,   92,
+ /*   340 */    93,   83,  823,  823,  835,  838,  827,  827,   90,   90,
+ /*   350 */    91,   91,   91,   91,  900,   89,   89,   89,   89,   88,
+ /*   360 */    88,   87,   87,   87,   86,  343,  319,  374,  311,  977,
+ /*   370 */   371,    1,  915,  437,   92,   93,   83,  823,  823,  835,
+ /*   380 */   838,  827,  827,   90,   90,   91,   91,   91,   91,  189,
+ /*   390 */    89,   89,   89,   89,   88,   88,   87,   87,   87,   86,
+ /*   400 */   343,  319,  724,  952,  937,  937,  149,  722,  952,   92,
+ /*   410 */    93,   83,  823,  823,  835,  838,  827,  827,   90,   90,
+ /*   420 */    91,   91,   91,   91,  438,   89,   89,   89,   89,   88,
+ /*   430 */    88,   87,   87,   87,   86,  343,  342,  942,  943,  951,
+ /*   440 */   698,  944,  978,  319,  957,   48,  938,  939,  719,  693,
+ /*   450 */    71,   92,   93,   83,  823,  823,  835,  838,  827,  827,
+ /*   460 */    90,   90,   91,   91,   91,   91,  324,   89,   89,   89,
+ /*   470 */    89,   88,   88,   87,   87,   87,   86,  343,  319,  416,
+ /*   480 */   407,  824,  824,  836,  839,   74,   92,   81,   83,  823,
+ /*   490 */   823,  835,  838,  827,  827,   90,   90,   91,   91,   91,
+ /*   500 */    91,  702,   89,   89,   89,   89,   88,   88,   87,   87,
+ /*   510 */    87,   86,  343,  319,  263,  658,  659,  660,  397,  111,
+ /*   520 */   335,  153,   93,   83,  823,  823,  835,  838,  827,  827,
+ /*   530 */    90,   90,   91,   91,   91,   91,  438,   89,   89,   89,
+ /*   540 */    89,   88,   88,   87,   87,   87,   86,  343,  319,  188,
+ /*   550 */   187,  186,  828,  941,  332,  219,  957,   48,   83,  823,
+ /*   560 */   823,  835,  838,  827,  827,   90,   90,   91,   91,   91,
+ /*   570 */    91,  960,   89,   89,   89,   89,   88,   88,   87,   87,
+ /*   580 */    87,   86,  343,   79,  433,  742,    3, 1178,  959,  352,
+ /*   590 */   741,  336,  796,  937,  937,  941,   79,  433,  734,    3,
+ /*   600 */   203,  160,  282,  395,  277,  394,  190,  896,  438,  404,
+ /*   610 */   745,   76,   77,  275,  291,  257,  357,  244,   78,  344,
+ /*   620 */   344,   85,   82,  168,   76,   77,  233,  401,  957,   48,
+ /*   630 */   436,   78,  344,  344,  281,  938,  939,  185,  443,  655,
+ /*   640 */   392,  389,  388,  436,  234,  280,  107,  422,  353,  341,
+ /*   650 */   340,  387,  897,  732,  215,  953,  123,  975,  312,  814,
+ /*   660 */   422,  440,  439,  416,  398,  802,  404,  877,  898,  123,
+ /*   670 */   725,  876,  814,  893,  440,  439,  215,  953,  802,  355,
+ /*   680 */   726,  701,  384,  438,  775,  375,   22,  438,  404,   79,
+ /*   690 */   433,  232,    3,  189,  417,  874,  807,  807,  807,  809,
+ /*   700 */    18,   54,  148,  957,   48,  960,  113,  957,    9,  807,
+ /*   710 */   807,  807,  809,   18,  314,  123,  752,   76,   77,  746,
+ /*   720 */   123,  329,  959,  870,   78,  344,  344,  113,  354,  363,
+ /*   730 */    85,   82,  168,  347,  964,  964,  436,  774,  416,  418,
+ /*   740 */   411,   23, 1244, 1244,   79,  433,  361,    3,  166,   91,
+ /*   750 */    91,   91,   91,  422,   89,   89,   89,   89,   88,   88,
+ /*   760 */    87,   87,   87,   86,  343,  814,  438,  440,  439,  796,
+ /*   770 */   324,  802,   76,   77,  793,  275,  123,  438,  364,   78,
+ /*   780 */   344,  344,  868,   85,   82,  168,  957,    9,  399,  747,
+ /*   790 */   364,  436,  257,  362,  256,  937,  937,  957,   30,  893,
+ /*   800 */   331,  216,  807,  807,  807,  809,   18,  113,  422,   89,
+ /*   810 */    89,   89,   89,   88,   88,   87,   87,   87,   86,  343,
+ /*   820 */   814,  113,  440,  439,  796,  185,  802,  292,  392,  389,
+ /*   830 */   388,  123,  113,  924,    2,  800,  700,  938,  939,  387,
+ /*   840 */    69,  433,  438,    3,  218,  110,  742,  257,  362,  256,
+ /*   850 */   438,  741,  937,  937,  896,  363,  222,  807,  807,  807,
+ /*   860 */   809,   18,  957,   47,  937,  937,  937,  937,   76,   77,
+ /*   870 */   957,    9,  370,  908,  217,   78,  344,  344,  681,  309,
+ /*   880 */   308,  307,  206,  305,  224,  263,  668,  436,  341,  340,
+ /*   890 */   438,  228,  251,  144,  938,  939,  937,  937,  671,  897,
+ /*   900 */   328, 1263,   96,  438,  422,  800,  938,  939,  938,  939,
+ /*   910 */   957,   48,  405,  148,  293,  898,  814,  421,  440,  439,
+ /*   920 */   681,  763,  802,  957,    9,  318,  220,  162,  161,  170,
+ /*   930 */   406,  239,  957,    8,  194,  687,  687,  414,  938,  939,
+ /*   940 */   238,  963,  937,  937,  225,  412,  949,  369,  961,  212,
+ /*   950 */   962,  172,  761,  807,  807,  807,  809,   18,  173,  369,
+ /*   960 */   176,  123,  171,  113,  248,  956,  250,  438,  360,  800,
+ /*   970 */   376,  369,  236,  964,  964,  814,  294,  808,  191,  165,
+ /*   980 */   856,  802,  263,  320,  938,  939,  237,  957,   34,  408,
+ /*   990 */    91,   91,   91,   91,   84,   89,   89,   89,   89,   88,
+ /*  1000 */    88,   87,   87,   87,   86,  343,  705,  956,  438,  240,
+ /*  1010 */   351,  762,  807,  807,  807,  438,  249, 1183,  438,  393,
+ /*  1020 */   438,  380,  438,  899,  167,  438,  409,  706,  957,   35,
+ /*  1030 */   677,  325,  221,  438,  337,  957,   11,  438,  957,   26,
+ /*  1040 */   957,   36,  957,   37,  255,  957,   38,  438,  263,  438,
+ /*  1050 */   761,  438,  333,  957,   27,  438,  223,  957,   28,  438,
+ /*  1060 */   694,  438,   67,  438,   65,  438,  866,  957,   39,  957,
+ /*  1070 */    40,  957,   41,  427,  438,  957,   10,  438,  776,  957,
+ /*  1080 */    42,  957,   98,  957,   43,  957,   44,  777,  438,  350,
+ /*  1090 */   438,   75,  438,   73,  957,   31,  438,  957,   45,  438,
+ /*  1100 */   263,  438,  694,  438,  761,  438,  891,  438,  957,   46,
+ /*  1110 */   957,   32,  957,  115,  438,  270,  957,  116,  955,  957,
+ /*  1120 */   117,  957,   52,  957,   33,  957,   99,  957,   49,  730,
+ /*  1130 */   438,  913,  438,   19,  957,  100,  438,  348,  438,  113,
+ /*  1140 */   438,  262,  696,  438,  263,  438,  674,  438,   20,  438,
+ /*  1150 */   957,  101,  957,   97,  438,  263,  957,  114,  957,  112,
+ /*  1160 */   957,  105,  113,  957,  104,  957,  102,  957,  103,  957,
+ /*  1170 */    51,  438,  148,  438,  957,   53,  167,  438,  263,  113,
+ /*  1180 */   304,  311,  916,  367,  315,  864,  252,  265,  209,  268,
+ /*  1190 */   420,  957,   50,  957,   25,  424,  731,  957,   29,  434,
+ /*  1200 */   325,  428,  761,  432,  326,  124, 1273,  214,  165,  714,
+ /*  1210 */   863,  912,  810,  798,  313,  158,  193,  365,  258,  727,
+ /*  1220 */   368,   67,  385,  273,  739,  199,   67,   70,  113,  704,
+ /*  1230 */   703,  711,  712,  888,  113,  770,  113,  859,  193,  887,
+ /*  1240 */   199,  873,  873,  679,  872,  872,  109,  372,  259,  264,
+ /*  1250 */   267,  284,  863,  269,  810,  978,  271,  715,  699,  276,
+ /*  1260 */   768,  286,  799,  288,  150,  748,  759,  419,  296,  297,
+ /*  1270 */   806,  682,  676,  665,  664,  666,  931,    6,  310,  390,
+ /*  1280 */   356,  243,  247,  254,  890,  366,  163,  290,  423,  302,
+ /*  1290 */   934,  159,  972,  196,  126,  907,  905,  969,   55,   58,
+ /*  1300 */   327,  279,  861,  136,  147,  698,  860,   95,  415,  121,
+ /*  1310 */    65,  358,  359,  383,  175,  379,   61,  373,  180,  261,
+ /*  1320 */   151,  875,  129,  145,  760,  210,  181,  381,  266,  667,
+ /*  1330 */   182,  183,  131,  139,  132,  790,  242,  133,  134,  787,
+ /*  1340 */   246,  795,  245,  396,  892,  334,  696,  410,  855,  718,
+ /*  1350 */   717,  316,   64,   72,   66,  716,  195,  843,  338,  709,
+ /*  1360 */   690,  317,  413,  689,  756,  278,  688,  708,  946,  283,
+ /*  1370 */   204,  673,   21,  932,  229,  208,  441,  757,  285,  426,
+ /*  1380 */   205,  430,  207,  755,  442,  662,  118,  654,  661,  656,
+ /*  1390 */   230,  345,  157,  235,  169,  119,  108,  226,  349,  321,
+ /*  1400 */   106,  871,  127,  869,  287,  794,  130,  120,  300,  754,
+ /*  1410 */   738,  289,  298,  299,  301,  728,  174,  128,  253,  886,
+ /*  1420 */   135,  137,   59,   60,  138,  177,  885,  889,    7,  178,
+ /*  1430 */    12,  231,  179,  878,  260,  193,  140,  966,  378,  141,
+ /*  1440 */   152,  670,  280,  382,  184,  274,  386,  391,  142,   62,
+ /*  1450 */    13,   14,  707,   63,  227,  322,  125,  122,  813,  812,
+ /*  1460 */   841,   15,    4,  736,  740,  164,  211,  213,  403,  769,
+ /*  1470 */   192,  143,  764,   70,   16,   17,   67,  842,  840,  895,
+ /*  1480 */   845,  894,  198,  197,  921,  154,  425,  201,  922,  155,
+ /*  1490 */   200,  927,  429,  844,  156,  202,  811,  680,   80, 1265,
+ /*  1500 */   303,  306,  981, 1264,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     0 */    19,  144,  145,  146,  147,   24,    1,    2,   27,   80,
- /*    10 */    81,   82,   83,   84,   85,   86,   87,   88,   89,   90,
- /*    20 */    91,   92,   93,   94,   95,   91,   92,   93,   94,   95,
- /*    30 */    19,   50,   51,   80,   81,   82,   83,   27,   85,   86,
- /*    40 */    87,   88,   89,   90,   91,   92,   93,   94,   95,  137,
- /*    50 */   177,  139,   71,   72,   73,   74,   75,   76,   77,   78,
- /*    60 */    79,   80,   81,   82,   83,   95,   85,   86,   87,   88,
- /*    70 */    89,   90,   91,   92,   93,   94,   95,   19,   97,   85,
- /*    80 */    86,   87,   88,   89,   90,   91,   92,   93,   94,   95,
- /*    90 */   152,   33,  212,  173,   27,   28,  223,  224,  225,  152,
- /*   100 */    42,  181,  152,  223,  224,  225,   95,   97,   50,   51,
- /*   110 */    99,  100,  101,  102,  103,  104,  105,   27,   28,   59,
- /*   120 */   223,  224,  225,  112,  174,  175,   66,   94,   95,   71,
- /*   130 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
- /*   140 */    82,   83,  195,   85,   86,   87,   88,   89,   90,   91,
- /*   150 */    92,   93,   94,   95,   19,  197,   89,   90,  220,  209,
- /*   160 */   210,   26,  119,  120,   97,   98,  208,  100,  108,  109,
- /*   170 */   110,  152,  157,  152,  107,  152,  109,   89,   90,   91,
- /*   180 */    92,   93,   94,   95,  163,   50,   51,   97,   98,   99,
- /*   190 */    55,   66,  102,  103,  104,  174,  175,  174,  175,  132,
- /*   200 */   133,  192,  193,  113,   66,   19,   71,   72,   73,   74,
- /*   210 */    75,   76,   77,   78,   79,   80,   81,   82,   83,  198,
- /*   220 */    85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
- /*   230 */    95,  152,  209,  210,  148,  149,   50,   51,  100,   53,
- /*   240 */   154,   59,  156,  174,  229,   27,   28,  232,  163,  163,
- /*   250 */    22,  192,  193,  174,  175,   27,   28,   71,   72,   73,
- /*   260 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*   270 */   251,   85,   86,   87,   88,   89,   90,   91,   92,   93,
- /*   280 */    94,   95,   19,  198,  198,  152,  152,   24,  209,  210,
- /*   290 */   108,  109,  110,  196,  197,   27,   28,   69,  164,  165,
- /*   300 */   152,  119,  120,   27,   28,  208,   99,   27,   28,  102,
- /*   310 */   103,  104,  152,   50,   51,   97,   98,   89,   90,  185,
- /*   320 */   113,  187,   22,  177,  174,   97,   58,   27,   28,  101,
- /*   330 */   115,  245,  117,  118,   71,   72,   73,   74,   75,   76,
- /*   340 */    77,   78,   79,   80,   81,   82,   83,   11,   85,   86,
- /*   350 */    87,   88,   89,   90,   91,   92,   93,   94,   95,   19,
- /*   360 */   132,  133,  134,   23,  152,   97,   98,   91,  174,  223,
- /*   370 */   224,  225,  239,   97,   98,  187,   22,   97,   98,   27,
- /*   380 */    28,   27,   28,  152,  223,  224,  225,  239,  152,  163,
- /*   390 */    50,   51,  170,  171,  172,   59,  160,   97,   98,  239,
- /*   400 */   164,  165,   66,  242,  124,  174,  175,  195,   22,   23,
- /*   410 */    69,   71,   72,   73,   74,   75,   76,   77,   78,   79,
- /*   420 */    80,   81,   82,   83,  198,   85,   86,   87,   88,   89,
- /*   430 */    90,   91,   92,   93,   94,   95,   19,   12,   97,   21,
- /*   440 */    23,  152,  101,  152,  108,  109,  110,  221,  152,   97,
- /*   450 */    98,   97,   98,  152,   29,  243,   70,  226,   23,  233,
- /*   460 */    26,   26,  152,  152,  238,  174,  175,   50,   51,   22,
- /*   470 */    45,   24,   47,  132,  133,  134,  124,   22,   23,  188,
- /*   480 */   163,   26,  152,   65,   59,  174,  175,  163,   71,   72,
- /*   490 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
- /*   500 */    83,  152,   85,   86,   87,   88,   89,   90,   91,   92,
- /*   510 */    93,   94,   95,   19,   19,  198,  152,   23,  152,  152,
- /*   520 */   209,  103,  198,  174,  175,   70,  152,   50,   51,  219,
- /*   530 */   213,  214,  152,   98,  152,  171,  172,  188,  171,  172,
- /*   540 */   174,  175,  248,  249,   50,   51,   51,  251,  174,  175,
- /*   550 */   220,   74,   75,  152,  188,  152,  174,  175,  140,  124,
- /*   560 */    26,  163,  188,   16,  130,   71,   72,   73,   74,   75,
- /*   570 */    76,   77,   78,   79,   80,   81,   82,   83,  101,   85,
- /*   580 */    86,   87,   88,   89,   90,   91,   92,   93,   94,   95,
- /*   590 */    19,  209,  196,  197,   23,  231,  198,   12,  231,  219,
- /*   600 */    37,   22,  107,   24,  208,  116,   27,  112,  201,   62,
- /*   610 */   121,   64,  152,  152,   29,   52,   66,  221,  211,  221,
- /*   620 */   219,   50,   51,   60,   89,   90,  152,   22,   23,  183,
- /*   630 */    45,   26,   47,   22,  174,  175,  238,  152,  164,  165,
- /*   640 */   106,   19,   71,   72,   73,   74,   75,   76,   77,   78,
- /*   650 */    79,   80,   81,   82,   83,  152,   85,   86,   87,   88,
- /*   660 */    89,   90,   91,   92,   93,   94,   95,  132,  133,  119,
- /*   670 */   120,  163,   50,   51,  111,   70,   97,  174,  175,  181,
- /*   680 */   182,  170,  171,  172,    0,    1,    2,  140,  190,  108,
- /*   690 */   109,  110,   51,   71,   72,   73,   74,   75,   76,   77,
- /*   700 */    78,   79,   80,   81,   82,   83,  198,   85,   86,   87,
- /*   710 */    88,   89,   90,   91,   92,   93,   94,   95,   19,  152,
- /*   720 */   152,  152,   22,  166,  152,  168,  169,   27,   19,  152,
- /*   730 */    26,   19,  152,  122,  152,   24,  152,   28,   27,  152,
- /*   740 */    28,  174,  175,  174,  175,  152,  174,  175,  107,   50,
- /*   750 */    51,  174,  175,   22,  174,  175,  174,  175,  174,  175,
- /*   760 */   138,  174,  175,    7,    8,    9,   16,  174,  175,  152,
- /*   770 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
- /*   780 */    81,   82,   83,  152,   85,   86,   87,   88,   89,   90,
- /*   790 */    91,   92,   93,   94,   95,   19,  152,   97,  152,   31,
- /*   800 */    24,  152,   98,   35,  101,  174,  175,  152,   97,  152,
- /*   810 */    79,  152,   62,  152,   64,  112,  152,   49,  174,  175,
- /*   820 */   174,  175,  152,  174,  175,  152,   50,   51,  124,  174,
- /*   830 */   175,  174,  175,  174,  175,  174,  175,  138,  174,  175,
- /*   840 */    22,   23,  152,  152,  174,  175,   19,   71,   72,   73,
- /*   850 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*   860 */   152,   85,   86,   87,   88,   89,   90,   91,   92,   93,
- /*   870 */    94,   95,  152,  108,  109,  110,  152,   50,   51,  146,
- /*   880 */   147,   23,  174,  175,   26,  195,  195,  152,   70,  152,
- /*   890 */   168,  169,  152,   26,  174,  175,  152,   19,   71,   72,
- /*   900 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
- /*   910 */    83,  152,   85,   86,   87,   88,   89,   90,   91,   92,
- /*   920 */    93,   94,   95,  152,  246,  247,  213,  214,   50,   51,
- /*   930 */   195,  152,  195,  174,  175,  195,  100,  101,  152,  195,
- /*   940 */   152,  152,    7,    8,  152,  174,  175,  163,   19,   71,
- /*   950 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
- /*   960 */    82,   83,  152,   85,   86,   87,   88,   89,   90,   91,
- /*   970 */    92,   93,   94,   95,  152,   27,  152,  189,  189,   50,
- /*   980 */    51,  195,  198,  152,  174,  175,   33,  132,  133,  152,
- /*   990 */   123,  163,  163,  163,  152,   42,  174,  175,  152,   19,
- /*  1000 */   152,   72,   73,   74,   75,   76,   77,   78,   79,   80,
- /*  1010 */    81,   82,   83,  152,   85,   86,   87,   88,   89,   90,
- /*  1020 */    91,   92,   93,   94,   95,  152,  198,  198,  198,   23,
- /*  1030 */    50,   51,   26,  152,   23,  174,  175,   26,   23,   23,
- /*  1040 */    23,   26,   26,   26,  152,   97,   23,  174,  175,   26,
- /*  1050 */   132,  133,  152,   73,   74,   75,   76,   77,   78,   79,
- /*  1060 */    80,   81,   82,   83,  152,   85,   86,   87,   88,   89,
- /*  1070 */    90,   91,   92,   93,   94,   95,   19,   20,   23,   22,
- /*  1080 */    23,   26,  152,  152,   27,   28,  174,  175,  152,   19,
- /*  1090 */    20,   27,   22,  183,  183,   38,  152,   27,   28,  152,
- /*  1100 */    23,  152,  152,   26,  174,  175,  152,  152,   38,  152,
- /*  1110 */    23,  152,   27,   26,   57,  152,  215,  163,  152,  152,
- /*  1120 */   152,  174,  175,   66,  174,  175,   69,   57,  174,  175,
- /*  1130 */   152,  174,  175,  174,  175,  212,   66,  174,  175,   69,
- /*  1140 */   174,  175,  174,  175,  152,  152,   89,   90,  152,  193,
- /*  1150 */   152,  152,  198,   96,   97,   98,   91,  152,  101,   89,
- /*  1160 */    90,   97,  152,  209,  210,  152,   96,   97,   98,  235,
- /*  1170 */   152,  101,  174,  175,  152,   19,   20,  152,   22,  174,
- /*  1180 */   175,  116,   97,   27,   28,  152,  121,  174,  175,  132,
- /*  1190 */   133,  134,  135,  136,   38,  152,  174,  175,  152,  174,
- /*  1200 */   175,  152,  132,  133,  134,  135,  136,  234,  152,  212,
- /*  1210 */   150,  199,  212,   57,  212,  240,  240,  203,  178,  200,
- /*  1220 */   216,  186,  177,   19,   20,   69,   22,  203,  177,  182,
- /*  1230 */   177,   27,   28,  202,  200,  228,  216,  216,  155,   39,
- /*  1240 */   122,  159,   38,  159,   41,   89,   90,   91,  159,  241,
- /*  1250 */   241,   22,   96,   97,   98,  129,  126,  101,  222,  207,
- /*  1260 */   206,   57,   71,  191,  130,  207,  203,  206,   18,  194,
- /*  1270 */   244,  159,  194,   69,  194,  194,  203,   19,   20,   18,
- /*  1280 */    22,  158,  191,  191,  222,   27,   28,  159,  132,  133,
- /*  1290 */   134,  135,  136,   89,   90,  158,   38,  203,  137,   46,
- /*  1300 */    96,   97,   98,  237,  236,  101,  159,  159,  158,   22,
- /*  1310 */   179,  159,  158,  107,  159,   57,  158,  179,  176,  176,
- /*  1320 */   176,   48,  176,  184,  179,  106,  125,   69,  218,  178,
- /*  1330 */   107,  217,  217,  176,  218,  218,  132,  133,  134,  135,
- /*  1340 */   136,  176,  176,  184,  217,  159,  217,   89,   90,  159,
- /*  1350 */   218,  137,  227,  179,   96,   97,   98,   95,  179,  101,
- /*  1360 */     5,  128,  127,  230,  204,   10,   11,   12,   13,   14,
- /*  1370 */   230,  207,   17,  206,  205,  203,   25,  162,   26,  161,
- /*  1380 */    13,  153,    6,  153,    4,  151,  250,   32,  151,   34,
- /*  1390 */   132,  133,  134,  135,  136,  151,  151,  180,   43,  250,
- /*  1400 */   247,  180,    3,  167,   22,  142,   15,   68,   16,   23,
- /*  1410 */    23,   56,  120,  131,  111,   20,  123,   16,   63,  125,
- /*  1420 */     1,   66,   67,  123,   79,   79,  131,  111,   28,   36,
- /*  1430 */   122,    1,    5,   22,  107,   54,  140,   54,   26,   61,
- /*  1440 */    44,  107,   24,   20,   19,  112,  105,   53,   22,   40,
- /*  1450 */    22,   22,   30,  116,   23,   22,   53,   22,   53,   23,
- /*  1460 */    23,   23,   22,   11,   23,   22,  122,   23,   26,  114,
- /*  1470 */    23,   22,  124,   28,   26,   36,   26,   23,   23,   23,
- /*  1480 */   122,   23,   36,   26,   22,   24,   23,   36,   22,   22,
- /*  1490 */    26,   23,   22,   24,   23,   23,  141,   23,   22,  122,
- /*  1500 */    23,  122,   15,    1,  252,  252,  122,
+ /*     0 */    19,   95,   53,   97,   22,   24,   24,  101,   27,   28,
+ /*    10 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
+ /*    20 */    39,   40,   41,  152,   43,   44,   45,   46,   47,   48,
+ /*    30 */    49,   50,   51,   52,   53,   19,   55,   55,  132,  133,
+ /*    40 */   134,    1,    2,   27,   28,   29,   30,   31,   32,   33,
+ /*    50 */    34,   35,   36,   37,   38,   39,   40,   41,   92,   43,
+ /*    60 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
+ /*    70 */    47,   48,   49,   50,   51,   52,   53,   61,   97,   97,
+ /*    80 */    19,   49,   50,   51,   52,   53,   70,   26,   27,   28,
+ /*    90 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
+ /*   100 */    39,   40,   41,  152,   43,   44,   45,   46,   47,   48,
+ /*   110 */    49,   50,   51,   52,   53,  144,  145,  146,  147,   19,
+ /*   120 */   249,   22,  172,  172,  173,   52,   53,   27,   28,   29,
+ /*   130 */    30,   31,   32,   33,   34,   35,   36,   37,   38,   39,
+ /*   140 */    40,   41,   81,   43,   44,   45,   46,   47,   48,   49,
+ /*   150 */    50,   51,   52,   53,   55,   56,   19,  152,  207,  208,
+ /*   160 */   115,   24,  117,  118,   27,   28,   29,   30,   31,   32,
+ /*   170 */    33,   34,   35,   36,   37,   38,   39,   40,   41,   79,
+ /*   180 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
+ /*   190 */    53,   19,    0,    1,    2,   23,   97,   98,  193,   27,
+ /*   200 */    28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
+ /*   210 */    38,   39,   40,   41,  152,   43,   44,   45,   46,   47,
+ /*   220 */    48,   49,   50,   51,   52,   53,   19,   22,   23,  172,
+ /*   230 */    23,   26,  119,  120,   27,   28,   29,   30,   31,   32,
+ /*   240 */    33,   34,   35,   36,   37,   38,   39,   40,   41,  187,
+ /*   250 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
+ /*   260 */    53,   19,  221,  222,  223,   23,  168,  169,  170,   27,
+ /*   270 */    28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
+ /*   280 */    38,   39,   40,   41,  152,   43,   44,   45,   46,   47,
+ /*   290 */    48,   49,   50,   51,   52,   53,   19,  157,   22,   23,
+ /*   300 */    23,   96,   26,  172,   27,   28,   29,   30,   31,   32,
+ /*   310 */    33,   34,   35,   36,   37,   38,   39,   40,   41,  187,
+ /*   320 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
+ /*   330 */    53,   19,  108,  109,  110,  221,  222,  223,  185,   27,
+ /*   340 */    28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
+ /*   350 */    38,   39,   40,   41,  240,   43,   44,   45,   46,   47,
+ /*   360 */    48,   49,   50,   51,   52,   53,   19,  227,   22,   23,
+ /*   370 */   230,   22,   96,  152,   27,   28,   29,   30,   31,   32,
+ /*   380 */    33,   34,   35,   36,   37,   38,   39,   40,   41,   30,
+ /*   390 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
+ /*   400 */    53,   19,  190,  191,   55,   56,   24,  190,  191,   27,
+ /*   410 */    28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
+ /*   420 */    38,   39,   40,   41,  152,   43,   44,   45,   46,   47,
+ /*   430 */    48,   49,   50,   51,   52,   53,  168,  169,  170,  179,
+ /*   440 */   180,  171,   96,   19,  172,  173,   97,   98,  188,  179,
+ /*   450 */   138,   27,   28,   29,   30,   31,   32,   33,   34,   35,
+ /*   460 */    36,   37,   38,   39,   40,   41,  107,   43,   44,   45,
+ /*   470 */    46,   47,   48,   49,   50,   51,   52,   53,   19,  207,
+ /*   480 */   208,   30,   31,   32,   33,  138,   27,   28,   29,   30,
+ /*   490 */    31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
+ /*   500 */    41,  181,   43,   44,   45,   46,   47,   48,   49,   50,
+ /*   510 */    51,   52,   53,   19,  152,    7,    8,    9,   49,   22,
+ /*   520 */    19,   24,   28,   29,   30,   31,   32,   33,   34,   35,
+ /*   530 */    36,   37,   38,   39,   40,   41,  152,   43,   44,   45,
+ /*   540 */    46,   47,   48,   49,   50,   51,   52,   53,   19,  108,
+ /*   550 */   109,  110,  101,   55,   53,  193,  172,  173,   29,   30,
+ /*   560 */    31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
+ /*   570 */    41,  152,   43,   44,   45,   46,   47,   48,   49,   50,
+ /*   580 */    51,   52,   53,   19,   20,  116,   22,   23,  169,  170,
+ /*   590 */   121,  207,   85,   55,   56,   97,   19,   20,  195,   22,
+ /*   600 */    99,  100,  101,  102,  103,  104,  105,   12,  152,  206,
+ /*   610 */   210,   47,   48,  112,  152,  108,  109,  110,   54,   55,
+ /*   620 */    56,  221,  222,  223,   47,   48,  119,  120,  172,  173,
+ /*   630 */    66,   54,   55,   56,  101,   97,   98,   99,  148,  149,
+ /*   640 */   102,  103,  104,   66,  154,  112,  156,   83,  229,   47,
+ /*   650 */    48,  113,   57,  163,  194,  195,   92,  246,  247,   95,
+ /*   660 */    83,   97,   98,  207,  208,  101,  206,   59,   73,   92,
+ /*   670 */    75,   63,   95,  163,   97,   98,  194,  195,  101,  219,
+ /*   680 */    85,  181,   19,  152,  175,   77,  196,  152,  206,   19,
+ /*   690 */    20,  199,   22,   30,  163,   11,  132,  133,  134,  135,
+ /*   700 */   136,  209,  152,  172,  173,  152,  196,  172,  173,  132,
+ /*   710 */   133,  134,  135,  136,  164,   92,  213,   47,   48,   49,
+ /*   720 */    92,  186,  169,  170,   54,   55,   56,  196,  100,  219,
+ /*   730 */   221,  222,  223,  243,  132,  133,   66,  175,  207,  208,
+ /*   740 */   152,  231,  119,  120,   19,   20,  236,   22,  152,   38,
+ /*   750 */    39,   40,   41,   83,   43,   44,   45,   46,   47,   48,
+ /*   760 */    49,   50,   51,   52,   53,   95,  152,   97,   98,   85,
+ /*   770 */   107,  101,   47,   48,  163,  112,   92,  152,  152,   54,
+ /*   780 */    55,   56,  229,  221,  222,  223,  172,  173,  163,   49,
+ /*   790 */   152,   66,  108,  109,  110,   55,   56,  172,  173,  163,
+ /*   800 */   186,   22,  132,  133,  134,  135,  136,  196,   83,   43,
+ /*   810 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
+ /*   820 */    95,  196,   97,   98,   85,   99,  101,  152,  102,  103,
+ /*   830 */   104,   92,  196,  146,  147,  152,  181,   97,   98,  113,
+ /*   840 */    19,   20,  152,   22,  218,   22,  116,  108,  109,  110,
+ /*   850 */   152,  121,   55,   56,   12,  219,  218,  132,  133,  134,
+ /*   860 */   135,  136,  172,  173,   55,   56,   55,   56,   47,   48,
+ /*   870 */   172,  173,  236,  152,    5,   54,   55,   56,   55,   10,
+ /*   880 */    11,   12,   13,   14,  186,  152,   17,   66,   47,   48,
+ /*   890 */   152,  210,   16,   84,   97,   98,   55,   56,   21,   57,
+ /*   900 */   217,  122,   22,  152,   83,  152,   97,   98,   97,   98,
+ /*   910 */   172,  173,  152,  152,  224,   73,   95,   75,   97,   98,
+ /*   920 */    97,  124,  101,  172,  173,  164,  193,   47,   48,   60,
+ /*   930 */   163,   62,  172,  173,   24,   55,   56,  186,   97,   98,
+ /*   940 */    71,  100,   55,   56,  183,  207,  185,  152,  107,   23,
+ /*   950 */   109,   82,   26,  132,  133,  134,  135,  136,   89,  152,
+ /*   960 */    26,   92,   93,  196,   88,   55,   90,  152,   91,  152,
+ /*   970 */   217,  152,  152,  132,  133,   95,  152,   97,  211,  212,
+ /*   980 */   103,  101,  152,  114,   97,   98,  152,  172,  173,   19,
+ /*   990 */    38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
+ /*  1000 */    48,   49,   50,   51,   52,   53,   65,   97,  152,  152,
+ /*  1010 */   141,  124,  132,  133,  134,  152,  140,  140,  152,   78,
+ /*  1020 */   152,  233,  152,  193,   98,  152,   56,   86,  172,  173,
+ /*  1030 */   166,  167,  237,  152,  217,  172,  173,  152,  172,  173,
+ /*  1040 */   172,  173,  172,  173,  237,  172,  173,  152,  152,  152,
+ /*  1050 */   124,  152,  111,  172,  173,  152,  237,  172,  173,  152,
+ /*  1060 */    55,  152,   26,  152,  130,  152,  152,  172,  173,  172,
+ /*  1070 */   173,  172,  173,  249,  152,  172,  173,  152,   61,  172,
+ /*  1080 */   173,  172,  173,  172,  173,  172,  173,   70,  152,  193,
+ /*  1090 */   152,  137,  152,  139,  172,  173,  152,  172,  173,  152,
+ /*  1100 */   152,  152,   97,  152,   26,  152,  163,  152,  172,  173,
+ /*  1110 */   172,  173,  172,  173,  152,   16,  172,  173,   26,  172,
+ /*  1120 */   173,  172,  173,  172,  173,  172,  173,  172,  173,  163,
+ /*  1130 */   152,  152,  152,   22,  172,  173,  152,  241,  152,  196,
+ /*  1140 */   152,  193,  106,  152,  152,  152,  163,  152,   37,  152,
+ /*  1150 */   172,  173,  172,  173,  152,  152,  172,  173,  172,  173,
+ /*  1160 */   172,  173,  196,  172,  173,  172,  173,  172,  173,  172,
+ /*  1170 */   173,  152,  152,  152,  172,  173,   98,  152,  152,  196,
+ /*  1180 */   160,   22,   23,   19,  164,  193,  152,   88,  232,   90,
+ /*  1190 */   191,  172,  173,  172,  173,  163,  193,  172,  173,  166,
+ /*  1200 */   167,  163,  124,  163,  244,  245,   23,  211,  212,   26,
+ /*  1210 */    55,   23,   55,   23,   26,  123,   26,  152,   23,  193,
+ /*  1220 */    56,   26,   23,   23,   23,   26,   26,   26,  196,  100,
+ /*  1230 */   101,    7,    8,  152,  196,   23,  196,   23,   26,  152,
+ /*  1240 */    26,  132,  133,   23,  132,  133,   26,  152,  152,  152,
+ /*  1250 */   152,  210,   97,  152,   97,   96,  152,  152,  152,  152,
+ /*  1260 */   152,  210,  152,  210,  197,  152,  152,  152,  152,  152,
+ /*  1270 */   152,  152,  152,  152,  152,  152,  152,  198,  150,  176,
+ /*  1280 */   214,  201,  214,  238,  201,  238,  184,  214,  226,  200,
+ /*  1290 */   155,  198,   67,  122,  242,  159,  159,   69,  239,  239,
+ /*  1300 */   159,  175,  175,   22,  220,  180,  175,  129,  126,   27,
+ /*  1310 */   130,   18,  159,   18,  158,   74,  137,  159,  158,  234,
+ /*  1320 */   220,  235,  189,   22,  159,  159,  158,  177,  159,  159,
+ /*  1330 */   158,  158,  192,  189,  192,  205,  204,  192,  192,  205,
+ /*  1340 */   201,  189,  204,  107,  201,   76,  106,  125,  201,  174,
+ /*  1350 */   174,  177,  107,  137,  128,  174,  159,  159,   53,  182,
+ /*  1360 */   174,  177,  127,  176,  216,  174,  174,  182,  174,  215,
+ /*  1370 */    25,  162,   26,   13,  225,    6,  161,  216,  215,  177,
+ /*  1380 */   153,  177,  153,  216,  151,  151,  165,    4,  151,  151,
+ /*  1390 */   228,    3,   22,  142,   15,  165,  178,  178,   94,  248,
+ /*  1400 */    16,   23,  131,   23,  215,  120,  123,  165,  202,  216,
+ /*  1410 */   205,  215,  204,  203,  201,   20,  125,  111,   16,    1,
+ /*  1420 */   123,  131,   37,   37,  111,   64,    1,   56,    5,  122,
+ /*  1430 */    22,  228,  107,   80,  140,   26,   80,   87,   72,  107,
+ /*  1440 */    24,   20,  112,   19,  105,   23,   79,   79,   22,   22,
+ /*  1450 */    22,   22,   58,   22,   79,  248,  245,   68,   23,   23,
+ /*  1460 */    23,   22,   22,  116,   23,  122,   23,   23,   26,   56,
+ /*  1470 */    64,   22,  124,   26,   64,   64,   26,   23,   23,   23,
+ /*  1480 */    11,   23,   22,   26,   23,   22,   24,  122,   23,   22,
+ /*  1490 */    26,    1,   24,   23,   22,  122,   23,   23,   22,  122,
+ /*  1500 */    23,   15,  250,  122,
 };
-#define YY_SHIFT_USE_DFLT (-89)
-#define YY_SHIFT_COUNT (439)
-#define YY_SHIFT_MIN   (-88)
-#define YY_SHIFT_MAX   (1502)
+#define YY_SHIFT_USE_DFLT (-95)
+#define YY_SHIFT_COUNT (443)
+#define YY_SHIFT_MIN   (-94)
+#define YY_SHIFT_MAX   (1490)
 static const short yy_shift_ofst[] = {
- /*     0 */     5, 1057, 1355, 1070, 1204, 1204, 1204,   90,   60,  -19,
- /*    10 */    58,   58,  186, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
- /*    20 */    67,   67,  182,  336,  218,  550,  135,  263,  340,  417,
- /*    30 */   494,  571,  622,  699,  776,  827,  827,  827,  827,  827,
- /*    40 */   827,  827,  827,  827,  827,  827,  827,  827,  827,  827,
- /*    50 */   878,  827,  929,  980,  980, 1156, 1204, 1204, 1204, 1204,
- /*    60 */  1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
- /*    70 */  1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
- /*    80 */  1204, 1204, 1204, 1204, 1258, 1204, 1204, 1204, 1204, 1204,
- /*    90 */  1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,  -71,  -47,
- /*   100 */   -47,  -47,  -47,  -47,   -6,   88,  -66,  218,  218,  418,
- /*   110 */   495,  535,  535,   33,   43,   10,  -30,  -89,  -89,  -89,
- /*   120 */    11,  425,  425,  268,  455,  605,  218,  218,  218,  218,
- /*   130 */   218,  218,  218,  218,  218,  218,  218,  218,  218,  218,
- /*   140 */   218,  218,  218,  218,  218,  684,  138,   10,   43,  125,
- /*   150 */   125,  125,  125,  125,  125,  -89,  -89,  -89,  228,  341,
- /*   160 */   341,  207,  276,  300,  280,  352,  354,  218,  218,  218,
- /*   170 */   218,  218,  218,  218,  218,  218,  218,  218,  218,  218,
- /*   180 */   218,  218,  218,  218,  563,  563,  563,  218,  218,  435,
- /*   190 */   218,  218,  218,  579,  218,  218,  585,  218,  218,  218,
- /*   200 */   218,  218,  218,  218,  218,  218,  218,  581,  768,  711,
- /*   210 */   711,  711,  704,  215, 1065,  756,  434,  709,  709,  712,
- /*   220 */   434,  712,  534,  858,  641,  953,  709,  -88,  953,  953,
- /*   230 */   867,  489,  447, 1200, 1118, 1118, 1203, 1203, 1118, 1229,
- /*   240 */  1126, 1130, 1191, 1126, 1130, 1134, 1250, 1250, 1250, 1250,
- /*   250 */  1118, 1261, 1134, 1229, 1191, 1191, 1134, 1118, 1261, 1161,
- /*   260 */  1253, 1118, 1118, 1261, 1287, 1118, 1261, 1118, 1261, 1287,
- /*   270 */  1206, 1206, 1206, 1273, 1287, 1206, 1219, 1206, 1273, 1206,
- /*   280 */  1206, 1201, 1223, 1201, 1223, 1201, 1223, 1201, 1223, 1118,
- /*   290 */  1118, 1214, 1287, 1262, 1262, 1287, 1126, 1130, 1233, 1235,
- /*   300 */  1134, 1351, 1352, 1367, 1367, 1376, 1376, 1376, 1376,  -89,
- /*   310 */   -89,  -89,  -89,  -89,  -89,  477,  547,  386,  818,  750,
- /*   320 */   765,  700, 1006,  731, 1011, 1015, 1016, 1017,  948,  836,
- /*   330 */   935,  703, 1023, 1055, 1064, 1077,  855,  918, 1087, 1085,
- /*   340 */   611, 1380, 1399, 1382, 1263, 1391, 1339, 1392, 1386, 1387,
- /*   350 */  1292, 1282, 1303, 1293, 1395, 1294, 1401, 1419, 1300, 1295,
- /*   360 */  1345, 1346, 1316, 1400, 1393, 1308, 1430, 1427, 1411, 1327,
- /*   370 */  1296, 1381, 1412, 1383, 1378, 1396, 1334, 1418, 1423, 1425,
- /*   380 */  1333, 1341, 1426, 1394, 1428, 1429, 1431, 1433, 1403, 1422,
- /*   390 */  1435, 1405, 1409, 1436, 1437, 1438, 1337, 1440, 1441, 1443,
- /*   400 */  1442, 1344, 1444, 1447, 1445, 1439, 1449, 1348, 1448, 1446,
- /*   410 */  1450, 1451, 1448, 1454, 1455, 1456, 1457, 1458, 1462, 1452,
- /*   420 */  1463, 1466, 1461, 1464, 1468, 1467, 1469, 1464, 1471, 1470,
- /*   430 */  1472, 1474, 1476, 1358, 1377, 1379, 1384, 1477, 1487, 1502,
+ /*     0 */    40,  564,  869,  577,  725,  725,  725,  739,  -19,   16,
+ /*    10 */    16,  100,  725,  725,  725,  725,  725,  725,  725,  841,
+ /*    20 */   841,  538,  507,  684,  623,   61,  137,  172,  207,  242,
+ /*    30 */   277,  312,  347,  382,  424,  424,  424,  424,  424,  424,
+ /*    40 */   424,  424,  424,  424,  424,  424,  424,  424,  424,  459,
+ /*    50 */   424,  494,  529,  529,  670,  725,  725,  725,  725,  725,
+ /*    60 */   725,  725,  725,  725,  725,  725,  725,  725,  725,  725,
+ /*    70 */   725,  725,  725,  725,  725,  725,  725,  725,  725,  725,
+ /*    80 */   725,  725,  725,  821,  725,  725,  725,  725,  725,  725,
+ /*    90 */   725,  725,  725,  725,  725,  725,  725,  952,  711,  711,
+ /*   100 */   711,  711,  711,  766,   23,   32,  811,  877,  663,  602,
+ /*   110 */   602,  811,   73,  113,  -51,  -95,  -95,  -95,  501,  501,
+ /*   120 */   501,  595,  595,  809,  205,  276,  811,  811,  811,  811,
+ /*   130 */   811,  811,  811,  811,  811,  811,  811,  811,  811,  811,
+ /*   140 */   811,  811,  811,  811,  811,  811,  192,  628,  498,  498,
+ /*   150 */   113,  -34,  -34,  -34,  -34,  -34,  -34,  -95,  -95,  -95,
+ /*   160 */   880,  -94,  -94,  726,  740,   99,  797,  887,  349,  811,
+ /*   170 */   811,  811,  811,  811,  811,  811,  811,  811,  811,  811,
+ /*   180 */   811,  811,  811,  811,  811,  811,  941,  941,  941,  811,
+ /*   190 */   811,  926,  811,  811,  811,  -18,  811,  811,  842,  811,
+ /*   200 */   811,  811,  811,  811,  811,  811,  811,  811,  811,  224,
+ /*   210 */   608,  910,  910,  910, 1078,   45,  469,  508,  934,  970,
+ /*   220 */   970, 1164,  934, 1164, 1036, 1183,  359, 1017,  970,  954,
+ /*   230 */  1017, 1017, 1092,  730,  497, 1225, 1171, 1171, 1228, 1228,
+ /*   240 */  1171, 1281, 1178, 1182, 1282, 1178, 1182, 1180, 1293, 1293,
+ /*   250 */  1293, 1293, 1171, 1295, 1180, 1281, 1282, 1282, 1180, 1171,
+ /*   260 */  1295, 1179, 1241, 1171, 1171, 1295, 1301, 1171, 1295, 1171,
+ /*   270 */  1295, 1301, 1236, 1236, 1236, 1269, 1301, 1236, 1240, 1236,
+ /*   280 */  1269, 1236, 1236, 1222, 1245, 1222, 1245, 1222, 1245, 1222,
+ /*   290 */  1245, 1171, 1171, 1216, 1301, 1305, 1305, 1301, 1178, 1182,
+ /*   300 */  1226, 1235, 1180, 1345, 1346, 1360, 1360, 1369, 1369, 1369,
+ /*   310 */  1369,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  451,
+ /*   320 */   876,  346, 1159, 1099,  441,  823, 1188, 1111, 1190, 1195,
+ /*   330 */  1199, 1200, 1005, 1129, 1224,  533, 1201, 1212, 1155, 1214,
+ /*   340 */  1109, 1112, 1220, 1157,  779, 1383, 1388, 1370, 1251, 1379,
+ /*   350 */  1304, 1384, 1378, 1380, 1285, 1271, 1306, 1283, 1395, 1291,
+ /*   360 */  1402, 1418, 1297, 1290, 1385, 1386, 1313, 1371, 1361, 1307,
+ /*   370 */  1425, 1423, 1408, 1325, 1294, 1353, 1409, 1356, 1350, 1366,
+ /*   380 */  1332, 1416, 1421, 1424, 1330, 1339, 1426, 1367, 1427, 1428,
+ /*   390 */  1422, 1429, 1368, 1394, 1431, 1375, 1389, 1435, 1436, 1437,
+ /*   400 */  1347, 1439, 1441, 1440, 1442, 1343, 1443, 1444, 1413, 1406,
+ /*   410 */  1449, 1348, 1447, 1410, 1450, 1411, 1447, 1454, 1455, 1456,
+ /*   420 */  1457, 1458, 1460, 1469, 1461, 1463, 1462, 1464, 1465, 1467,
+ /*   430 */  1468, 1464, 1470, 1472, 1473, 1474, 1476, 1365, 1373, 1377,
+ /*   440 */  1381, 1477, 1486, 1490,
 };
-#define YY_REDUCE_USE_DFLT (-144)
-#define YY_REDUCE_COUNT (314)
-#define YY_REDUCE_MIN   (-143)
-#define YY_REDUCE_MAX   (1245)
+#define YY_REDUCE_USE_DFLT (-130)
+#define YY_REDUCE_COUNT (318)
+#define YY_REDUCE_MIN   (-129)
+#define YY_REDUCE_MAX   (1242)
 static const short yy_reduce_ofst[] = {
- /*     0 */  -143,  954,   86,   21,  -50,   23,   79,  134,  226, -120,
- /*    10 */  -127,  146,  161,  291,  349,  366,  311,  382,  374,  231,
- /*    20 */   364,  367,  396,  398,  236,  317, -103, -103, -103, -103,
- /*    30 */  -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- /*    40 */  -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- /*    50 */  -103, -103, -103, -103, -103,  460,  503,  567,  569,  572,
- /*    60 */   577,  580,  582,  584,  587,  593,  631,  644,  646,  649,
- /*    70 */   655,  657,  659,  661,  664,  670,  708,  720,  759,  771,
- /*    80 */   810,  822,  861,  873,  912,  930,  947,  950,  957,  959,
- /*    90 */   963,  966,  968,  998, 1005, 1013, 1022, 1025, -103, -103,
- /*   100 */  -103, -103, -103, -103, -103, -103, -103,  474,  212,   15,
- /*   110 */   498,  222,  511, -103,   97,  557, -103, -103, -103, -103,
- /*   120 */   -80,    9,   59,   19,  294,  294,  -53,  -62,  690,  691,
- /*   130 */   735,  737,  740,  744,  133,  310,  148,  330,  160,  380,
- /*   140 */   786,  788,  401,  296,  789,  733,   85,  722,  -42,  324,
- /*   150 */   508,  784,  828,  829,  830,  678,  713,  407,   69,  150,
- /*   160 */   194,  188,  289,  301,  403,  461,  485,  568,  617,  673,
- /*   170 */   724,  779,  792,  824,  831,  837,  842,  846,  848,  881,
- /*   180 */   892,  900,  931,  936,  446,  910,  911,  944,  949,  901,
- /*   190 */   955,  967,  978,  923,  992,  993,  956,  996,  999, 1010,
- /*   200 */   289, 1018, 1033, 1043, 1046, 1049, 1056,  934,  973,  997,
- /*   210 */  1000, 1002,  901, 1012, 1019, 1060, 1014, 1004, 1020,  975,
- /*   220 */  1024,  976, 1040, 1035, 1047, 1045, 1021, 1007, 1051, 1053,
- /*   230 */  1031, 1034, 1083, 1026, 1082, 1084, 1008, 1009, 1089, 1036,
- /*   240 */  1052, 1054, 1072, 1058, 1061, 1063, 1075, 1078, 1080, 1081,
- /*   250 */  1112, 1123, 1073, 1062, 1091, 1092, 1094, 1128, 1137, 1066,
- /*   260 */  1068, 1147, 1148, 1150, 1131, 1152, 1154, 1155, 1158, 1138,
- /*   270 */  1142, 1143, 1144, 1139, 1145, 1146, 1151, 1157, 1159, 1165,
- /*   280 */  1166, 1110, 1114, 1116, 1115, 1117, 1127, 1132, 1129, 1186,
- /*   290 */  1190, 1125, 1174, 1133, 1140, 1179, 1164, 1167, 1169, 1160,
- /*   300 */  1172, 1215, 1218, 1228, 1230, 1234, 1237, 1244, 1245, 1136,
- /*   310 */  1149, 1153, 1217, 1221, 1236,
+ /*     0 */   -29,  531,  490,  625,  -49,  272,  456,  510,  400,  509,
+ /*    10 */   562,  114,  535,  614,  698,  384,  738,  751,  690,  419,
+ /*    20 */   553,  761,  460,  636,  767,   41,   41,   41,   41,   41,
+ /*    30 */    41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+ /*    40 */    41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+ /*    50 */    41,   41,   41,   41,  760,  815,  856,  863,  866,  868,
+ /*    60 */   870,  873,  881,  885,  895,  897,  899,  903,  907,  909,
+ /*    70 */   911,  913,  922,  925,  936,  938,  940,  944,  947,  949,
+ /*    80 */   951,  953,  955,  962,  978,  980,  984,  986,  988,  991,
+ /*    90 */   993,  995,  997, 1002, 1019, 1021, 1025,   41,   41,   41,
+ /*   100 */    41,   41,   41,   41,   41,   41,  896,  140,  260,   98,
+ /*   110 */   268, 1020,   41,  482,   41,   41,   41,   41,  270,  270,
+ /*   120 */   270,  212,  217, -129,  411,  411,  550,    5,  626,  362,
+ /*   130 */   733,  830,  992, 1003, 1026,  795,  683,  807,  638,  819,
+ /*   140 */   753,  948,   62,  817,  824,  132,  687,  611,  864, 1033,
+ /*   150 */   403,  943,  966,  983, 1032, 1038, 1040,  960,  996,  492,
+ /*   160 */   -50,   57,  131,  153,  221,  462,  588,  596,  675,  721,
+ /*   170 */   820,  834,  857,  914,  979, 1034, 1065, 1081, 1087, 1095,
+ /*   180 */  1096, 1097, 1098, 1101, 1104, 1105,  320,  500,  655, 1106,
+ /*   190 */  1107,  503, 1108, 1110, 1113,  681, 1114, 1115,  999, 1116,
+ /*   200 */  1117, 1118,  221, 1119, 1120, 1121, 1122, 1123, 1124,  788,
+ /*   210 */   956, 1041, 1051, 1053,  503, 1067, 1079, 1128, 1080, 1066,
+ /*   220 */  1068, 1045, 1083, 1047, 1103, 1102, 1125, 1126, 1073, 1062,
+ /*   230 */  1127, 1131, 1089, 1093, 1135, 1052, 1136, 1137, 1059, 1060,
+ /*   240 */  1141, 1084, 1130, 1132, 1133, 1134, 1138, 1139, 1140, 1142,
+ /*   250 */  1145, 1146, 1153, 1156, 1143, 1100, 1144, 1152, 1147, 1158,
+ /*   260 */  1160, 1086, 1085, 1165, 1166, 1168, 1150, 1169, 1172, 1170,
+ /*   270 */  1173, 1174, 1175, 1176, 1181, 1177, 1184, 1186, 1187, 1191,
+ /*   280 */  1185, 1192, 1194, 1148, 1154, 1161, 1163, 1167, 1189, 1193,
+ /*   290 */  1196, 1197, 1198, 1149, 1202, 1162, 1203, 1204, 1205, 1208,
+ /*   300 */  1210, 1206, 1213, 1209, 1215, 1227, 1229, 1233, 1234, 1237,
+ /*   310 */  1238, 1151, 1207, 1211, 1221, 1230, 1218, 1219, 1242,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   986, 1304, 1304, 1304, 1218, 1218, 1218, 1309, 1304, 1113,
- /*    10 */  1142, 1142, 1278, 1309, 1309, 1309, 1309, 1309, 1309, 1216,
- /*    20 */  1309, 1309, 1309, 1304, 1309, 1117, 1148, 1309, 1309, 1309,
- /*    30 */  1309, 1309, 1309, 1309, 1309, 1277, 1279, 1156, 1155, 1258,
- /*    40 */  1129, 1153, 1146, 1150, 1219, 1212, 1213, 1211, 1215, 1220,
- /*    50 */  1309, 1149, 1181, 1196, 1180, 1309, 1309, 1309, 1309, 1309,
- /*    60 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*    70 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*    80 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*    90 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1190, 1195,
- /*   100 */  1202, 1194, 1191, 1183, 1182, 1184, 1185, 1309, 1309, 1012,
- /*   110 */  1078, 1309, 1309, 1186, 1309, 1024, 1187, 1199, 1198, 1197,
- /*   120 */  1019, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   130 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   140 */  1309, 1309, 1309, 1309, 1309,  986, 1304, 1309, 1309, 1304,
- /*   150 */  1304, 1304, 1304, 1304, 1304, 1296, 1117, 1107, 1309, 1309,
- /*   160 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1284, 1282,
- /*   170 */  1309, 1231, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   180 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   190 */  1309, 1309, 1309, 1113, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   200 */  1309, 1309, 1309, 1309, 1309, 1309,  992, 1309, 1251, 1113,
- /*   210 */  1113, 1113, 1115, 1093, 1105,  994, 1152, 1131, 1131, 1263,
- /*   220 */  1152, 1263, 1049, 1072, 1046, 1142, 1131, 1214, 1142, 1142,
- /*   230 */  1114, 1105, 1309, 1289, 1122, 1122, 1281, 1281, 1122, 1161,
- /*   240 */  1147, 1136, 1082, 1147, 1136, 1152, 1089, 1089, 1089, 1089,
- /*   250 */  1122, 1009, 1152, 1161, 1082, 1082, 1152, 1122, 1009, 1257,
- /*   260 */  1255, 1122, 1122, 1009, 1224, 1122, 1009, 1122, 1009, 1224,
- /*   270 */  1080, 1080, 1080, 1064, 1224, 1080, 1049, 1080, 1064, 1080,
- /*   280 */  1080, 1135, 1130, 1135, 1130, 1135, 1130, 1135, 1130, 1122,
- /*   290 */  1122, 1309, 1224, 1228, 1228, 1224, 1147, 1136, 1145, 1143,
- /*   300 */  1152, 1015, 1067, 1002, 1002,  991,  991,  991,  991, 1301,
- /*   310 */  1301, 1296, 1051, 1051, 1034, 1309, 1309, 1309, 1309, 1309,
- /*   320 */  1309, 1026, 1309, 1233, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   330 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   340 */  1168, 1309,  987, 1291, 1309, 1309, 1288, 1309, 1309, 1309,
- /*   350 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   360 */  1309, 1309, 1309, 1309, 1309, 1261, 1309, 1309, 1309, 1309,
- /*   370 */  1309, 1309, 1254, 1253, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   380 */  1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   390 */  1309, 1309, 1309, 1309, 1309, 1309, 1096, 1309, 1309, 1309,
- /*   400 */  1100, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1144, 1309,
- /*   410 */  1137, 1309, 1217, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /*   420 */  1309, 1309, 1309, 1306, 1309, 1309, 1309, 1305, 1309, 1309,
- /*   430 */  1309, 1309, 1309, 1170, 1309, 1169, 1173, 1309, 1000, 1309,
+ /*     0 */  1254, 1244, 1244, 1244, 1178, 1178, 1178, 1244, 1075, 1104,
+ /*    10 */  1104, 1228, 1305, 1305, 1305, 1305, 1305, 1305, 1177, 1305,
+ /*    20 */  1305, 1305, 1305, 1244, 1079, 1110, 1305, 1305, 1305, 1305,
+ /*    30 */  1305, 1305, 1305, 1305, 1227, 1229, 1118, 1117, 1210, 1091,
+ /*    40 */  1115, 1108, 1112, 1179, 1173, 1174, 1172, 1176, 1180, 1305,
+ /*    50 */  1111, 1142, 1157, 1141, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*    60 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*    70 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*    80 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*    90 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1151, 1156, 1163,
+ /*   100 */  1155, 1152, 1144, 1143, 1145, 1146, 1305,  998, 1046, 1305,
+ /*   110 */  1305, 1305, 1147, 1305, 1148, 1160, 1159, 1158, 1235, 1262,
+ /*   120 */  1261, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   130 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   140 */  1305, 1305, 1305, 1305, 1305, 1305, 1254, 1244, 1004, 1004,
+ /*   150 */  1305, 1244, 1244, 1244, 1244, 1244, 1244, 1240, 1079, 1070,
+ /*   160 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   170 */  1232, 1230, 1305, 1191, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   180 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   190 */  1305, 1305, 1305, 1305, 1305, 1075, 1305, 1305, 1305, 1305,
+ /*   200 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1256, 1305,
+ /*   210 */  1205, 1075, 1075, 1075, 1077, 1059, 1069,  983, 1114, 1093,
+ /*   220 */  1093, 1294, 1114, 1294, 1021, 1276, 1018, 1104, 1093, 1175,
+ /*   230 */  1104, 1104, 1076, 1069, 1305, 1297, 1084, 1084, 1296, 1296,
+ /*   240 */  1084, 1123, 1109, 1098, 1049, 1109, 1098, 1114, 1055, 1055,
+ /*   250 */  1055, 1055, 1084,  995, 1114, 1123, 1049, 1049, 1114, 1084,
+ /*   260 */   995, 1209, 1291, 1084, 1084,  995, 1184, 1084,  995, 1084,
+ /*   270 */   995, 1184, 1047, 1047, 1047, 1036, 1184, 1047, 1021, 1047,
+ /*   280 */  1036, 1047, 1047, 1097, 1092, 1097, 1092, 1097, 1092, 1097,
+ /*   290 */  1092, 1084, 1084, 1305, 1184, 1188, 1188, 1184, 1109, 1098,
+ /*   300 */  1107, 1105, 1114, 1001, 1039, 1259, 1259, 1255, 1255, 1255,
+ /*   310 */  1255, 1302, 1302, 1240, 1271, 1271, 1023, 1023, 1271, 1305,
+ /*   320 */  1305, 1305, 1305, 1305, 1305, 1266, 1305, 1193, 1305, 1305,
+ /*   330 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   340 */  1305, 1305, 1305, 1305, 1129, 1305,  979, 1237, 1305, 1305,
+ /*   350 */  1236, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   360 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1293,
+ /*   370 */  1305, 1305, 1305, 1305, 1305, 1305, 1208, 1207, 1305, 1305,
+ /*   380 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   390 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /*   400 */  1061, 1305, 1305, 1305, 1280, 1305, 1305, 1305, 1305, 1305,
+ /*   410 */  1305, 1305, 1106, 1305, 1099, 1305, 1284, 1305, 1305, 1305,
+ /*   420 */  1305, 1305, 1305, 1305, 1305, 1305, 1305, 1246, 1305, 1305,
+ /*   430 */  1305, 1245, 1305, 1305, 1305, 1305, 1305, 1131, 1305, 1130,
+ /*   440 */  1134, 1305,  989, 1305,
 };
 /********** End of lemon-generated parsing tables *****************************/
 
@@ -128891,74 +131739,100 @@ static const YYACTIONTYPE yy_default[] = {
 static const YYCODETYPE yyFallback[] = {
     0,  /*          $ => nothing */
     0,  /*       SEMI => nothing */
-   27,  /*    EXPLAIN => ID */
-   27,  /*      QUERY => ID */
-   27,  /*       PLAN => ID */
-   27,  /*      BEGIN => ID */
+   55,  /*    EXPLAIN => ID */
+   55,  /*      QUERY => ID */
+   55,  /*       PLAN => ID */
+   55,  /*      BEGIN => ID */
     0,  /* TRANSACTION => nothing */
-   27,  /*   DEFERRED => ID */
-   27,  /*  IMMEDIATE => ID */
-   27,  /*  EXCLUSIVE => ID */
+   55,  /*   DEFERRED => ID */
+   55,  /*  IMMEDIATE => ID */
+   55,  /*  EXCLUSIVE => ID */
     0,  /*     COMMIT => nothing */
-   27,  /*        END => ID */
-   27,  /*   ROLLBACK => ID */
-   27,  /*  SAVEPOINT => ID */
-   27,  /*    RELEASE => ID */
+   55,  /*        END => ID */
+   55,  /*   ROLLBACK => ID */
+   55,  /*  SAVEPOINT => ID */
+   55,  /*    RELEASE => ID */
     0,  /*         TO => nothing */
     0,  /*      TABLE => nothing */
     0,  /*     CREATE => nothing */
-   27,  /*         IF => ID */
+   55,  /*         IF => ID */
     0,  /*        NOT => nothing */
     0,  /*     EXISTS => nothing */
-   27,  /*       TEMP => ID */
+   55,  /*       TEMP => ID */
     0,  /*         LP => nothing */
     0,  /*         RP => nothing */
     0,  /*         AS => nothing */
-   27,  /*    WITHOUT => ID */
+   55,  /*    WITHOUT => ID */
     0,  /*      COMMA => nothing */
+    0,  /*         OR => nothing */
+    0,  /*        AND => nothing */
+    0,  /*         IS => nothing */
+   55,  /*      MATCH => ID */
+   55,  /*    LIKE_KW => ID */
+    0,  /*    BETWEEN => nothing */
+    0,  /*         IN => nothing */
+    0,  /*     ISNULL => nothing */
+    0,  /*    NOTNULL => nothing */
+    0,  /*         NE => nothing */
+    0,  /*         EQ => nothing */
+    0,  /*         GT => nothing */
+    0,  /*         LE => nothing */
+    0,  /*         LT => nothing */
+    0,  /*         GE => nothing */
+    0,  /*     ESCAPE => nothing */
+    0,  /*     BITAND => nothing */
+    0,  /*      BITOR => nothing */
+    0,  /*     LSHIFT => nothing */
+    0,  /*     RSHIFT => nothing */
+    0,  /*       PLUS => nothing */
+    0,  /*      MINUS => nothing */
+    0,  /*       STAR => nothing */
+    0,  /*      SLASH => nothing */
+    0,  /*        REM => nothing */
+    0,  /*     CONCAT => nothing */
+    0,  /*    COLLATE => nothing */
+    0,  /*     BITNOT => nothing */
     0,  /*         ID => nothing */
     0,  /*    INDEXED => nothing */
-   27,  /*      ABORT => ID */
-   27,  /*     ACTION => ID */
-   27,  /*      AFTER => ID */
-   27,  /*    ANALYZE => ID */
-   27,  /*        ASC => ID */
-   27,  /*     ATTACH => ID */
-   27,  /*     BEFORE => ID */
-   27,  /*         BY => ID */
-   27,  /*    CASCADE => ID */
-   27,  /*       CAST => ID */
-   27,  /*   COLUMNKW => ID */
-   27,  /*   CONFLICT => ID */
-   27,  /*   DATABASE => ID */
-   27,  /*       DESC => ID */
-   27,  /*     DETACH => ID */
-   27,  /*       EACH => ID */
-   27,  /*       FAIL => ID */
-   27,  /*        FOR => ID */
-   27,  /*     IGNORE => ID */
-   27,  /*  INITIALLY => ID */
-   27,  /*    INSTEAD => ID */
-   27,  /*    LIKE_KW => ID */
-   27,  /*      MATCH => ID */
-   27,  /*         NO => ID */
-   27,  /*        KEY => ID */
-   27,  /*         OF => ID */
-   27,  /*     OFFSET => ID */
-   27,  /*     PRAGMA => ID */
-   27,  /*      RAISE => ID */
-   27,  /*  RECURSIVE => ID */
-   27,  /*    REPLACE => ID */
-   27,  /*   RESTRICT => ID */
-   27,  /*        ROW => ID */
-   27,  /*    TRIGGER => ID */
-   27,  /*     VACUUM => ID */
-   27,  /*       VIEW => ID */
-   27,  /*    VIRTUAL => ID */
-   27,  /*       WITH => ID */
-   27,  /*    REINDEX => ID */
-   27,  /*     RENAME => ID */
-   27,  /*   CTIME_KW => ID */
+   55,  /*      ABORT => ID */
+   55,  /*     ACTION => ID */
+   55,  /*      AFTER => ID */
+   55,  /*    ANALYZE => ID */
+   55,  /*        ASC => ID */
+   55,  /*     ATTACH => ID */
+   55,  /*     BEFORE => ID */
+   55,  /*         BY => ID */
+   55,  /*    CASCADE => ID */
+   55,  /*       CAST => ID */
+   55,  /*   COLUMNKW => ID */
+   55,  /*   CONFLICT => ID */
+   55,  /*   DATABASE => ID */
+   55,  /*       DESC => ID */
+   55,  /*     DETACH => ID */
+   55,  /*       EACH => ID */
+   55,  /*       FAIL => ID */
+   55,  /*        FOR => ID */
+   55,  /*     IGNORE => ID */
+   55,  /*  INITIALLY => ID */
+   55,  /*    INSTEAD => ID */
+   55,  /*         NO => ID */
+   55,  /*        KEY => ID */
+   55,  /*         OF => ID */
+   55,  /*     OFFSET => ID */
+   55,  /*     PRAGMA => ID */
+   55,  /*      RAISE => ID */
+   55,  /*  RECURSIVE => ID */
+   55,  /*    REPLACE => ID */
+   55,  /*   RESTRICT => ID */
+   55,  /*        ROW => ID */
+   55,  /*    TRIGGER => ID */
+   55,  /*     VACUUM => ID */
+   55,  /*       VIEW => ID */
+   55,  /*    VIRTUAL => ID */
+   55,  /*       WITH => ID */
+   55,  /*    REINDEX => ID */
+   55,  /*     RENAME => ID */
+   55,  /*   CTIME_KW => ID */
 };
 #endif /* YYFALLBACK */
 
@@ -128994,7 +131868,9 @@ struct yyParser {
 #ifdef YYTRACKMAXSTACKDEPTH
   int yyidxMax;                 /* Maximum value of yyidx */
 #endif
+#ifndef YYNOERRORRECOVERY
   int yyerrcnt;                 /* Shifts left before out of the error */
+#endif
   sqlite3ParserARG_SDECL                /* A place to hold %extra_argument */
 #if YYSTACKDEPTH<=0
   int yystksz;                  /* Current side of the stack */
@@ -129047,25 +131923,25 @@ static const char *const yyTokenName[] = {
   "ROLLBACK",      "SAVEPOINT",     "RELEASE",       "TO",          
   "TABLE",         "CREATE",        "IF",            "NOT",         
   "EXISTS",        "TEMP",          "LP",            "RP",          
-  "AS",            "WITHOUT",       "COMMA",         "ID",          
+  "AS",            "WITHOUT",       "COMMA",         "OR",          
+  "AND",           "IS",            "MATCH",         "LIKE_KW",     
+  "BETWEEN",       "IN",            "ISNULL",        "NOTNULL",     
+  "NE",            "EQ",            "GT",            "LE",          
+  "LT",            "GE",            "ESCAPE",        "BITAND",      
+  "BITOR",         "LSHIFT",        "RSHIFT",        "PLUS",        
+  "MINUS",         "STAR",          "SLASH",         "REM",         
+  "CONCAT",        "COLLATE",       "BITNOT",        "ID",          
   "INDEXED",       "ABORT",         "ACTION",        "AFTER",       
   "ANALYZE",       "ASC",           "ATTACH",        "BEFORE",      
   "BY",            "CASCADE",       "CAST",          "COLUMNKW",    
   "CONFLICT",      "DATABASE",      "DESC",          "DETACH",      
   "EACH",          "FAIL",          "FOR",           "IGNORE",      
-  "INITIALLY",     "INSTEAD",       "LIKE_KW",       "MATCH",       
-  "NO",            "KEY",           "OF",            "OFFSET",      
-  "PRAGMA",        "RAISE",         "RECURSIVE",     "REPLACE",     
-  "RESTRICT",      "ROW",           "TRIGGER",       "VACUUM",      
-  "VIEW",          "VIRTUAL",       "WITH",          "REINDEX",     
-  "RENAME",        "CTIME_KW",      "ANY",           "OR",          
-  "AND",           "IS",            "BETWEEN",       "IN",          
-  "ISNULL",        "NOTNULL",       "NE",            "EQ",          
-  "GT",            "LE",            "LT",            "GE",          
-  "ESCAPE",        "BITAND",        "BITOR",         "LSHIFT",      
-  "RSHIFT",        "PLUS",          "MINUS",         "STAR",        
-  "SLASH",         "REM",           "CONCAT",        "COLLATE",     
-  "BITNOT",        "STRING",        "JOIN_KW",       "CONSTRAINT",  
+  "INITIALLY",     "INSTEAD",       "NO",            "KEY",         
+  "OF",            "OFFSET",        "PRAGMA",        "RAISE",       
+  "RECURSIVE",     "REPLACE",       "RESTRICT",      "ROW",         
+  "TRIGGER",       "VACUUM",        "VIEW",          "VIRTUAL",     
+  "WITH",          "REINDEX",       "RENAME",        "CTIME_KW",    
+  "ANY",           "STRING",        "JOIN_KW",       "CONSTRAINT",  
   "DEFAULT",       "NULL",          "PRIMARY",       "UNIQUE",      
   "CHECK",         "REFERENCES",    "AUTOINCR",      "ON",          
   "INSERT",        "DELETE",        "UPDATE",        "SET",         
@@ -129082,28 +131958,28 @@ static const char *const yyTokenName[] = {
   "nm",            "savepoint_opt",  "create_table",  "create_table_args",
   "createkw",      "temp",          "ifnotexists",   "dbnm",        
   "columnlist",    "conslist_opt",  "table_options",  "select",      
-  "column",        "columnid",      "type",          "carglist",    
-  "typetoken",     "typename",      "signed",        "plus_num",    
-  "minus_num",     "ccons",         "term",          "expr",        
-  "onconf",        "sortorder",     "autoinc",       "eidlist_opt", 
-  "refargs",       "defer_subclause",  "refarg",        "refact",      
-  "init_deferred_pred_opt",  "conslist",      "tconscomma",    "tcons",       
-  "sortlist",      "eidlist",       "defer_subclause_opt",  "orconf",      
-  "resolvetype",   "raisetype",     "ifexists",      "fullname",    
-  "selectnowith",  "oneselect",     "with",          "multiselect_op",
-  "distinct",      "selcollist",    "from",          "where_opt",   
-  "groupby_opt",   "having_opt",    "orderby_opt",   "limit_opt",   
-  "values",        "nexprlist",     "exprlist",      "sclp",        
-  "as",            "seltablist",    "stl_prefix",    "joinop",      
-  "indexed_opt",   "on_opt",        "using_opt",     "idlist",      
-  "setlist",       "insert_cmd",    "idlist_opt",    "likeop",      
-  "between_op",    "in_op",         "case_operand",  "case_exprlist",
-  "case_else",     "uniqueflag",    "collate",       "nmnum",       
-  "trigger_decl",  "trigger_cmd_list",  "trigger_time",  "trigger_event",
-  "foreach_clause",  "when_clause",   "trigger_cmd",   "trnm",        
-  "tridxby",       "database_kw_opt",  "key_opt",       "add_column_fullname",
-  "kwcolumn_opt",  "create_vtab",   "vtabarglist",   "vtabarg",     
-  "vtabargtoken",  "lp",            "anylist",       "wqlist",      
+  "columnname",    "carglist",      "typetoken",     "typename",    
+  "signed",        "plus_num",      "minus_num",     "ccons",       
+  "term",          "expr",          "onconf",        "sortorder",   
+  "autoinc",       "eidlist_opt",   "refargs",       "defer_subclause",
+  "refarg",        "refact",        "init_deferred_pred_opt",  "conslist",    
+  "tconscomma",    "tcons",         "sortlist",      "eidlist",     
+  "defer_subclause_opt",  "orconf",        "resolvetype",   "raisetype",   
+  "ifexists",      "fullname",      "selectnowith",  "oneselect",   
+  "with",          "multiselect_op",  "distinct",      "selcollist",  
+  "from",          "where_opt",     "groupby_opt",   "having_opt",  
+  "orderby_opt",   "limit_opt",     "values",        "nexprlist",   
+  "exprlist",      "sclp",          "as",            "seltablist",  
+  "stl_prefix",    "joinop",        "indexed_opt",   "on_opt",      
+  "using_opt",     "idlist",        "setlist",       "insert_cmd",  
+  "idlist_opt",    "likeop",        "between_op",    "in_op",       
+  "case_operand",  "case_exprlist",  "case_else",     "uniqueflag",  
+  "collate",       "nmnum",         "trigger_decl",  "trigger_cmd_list",
+  "trigger_time",  "trigger_event",  "foreach_clause",  "when_clause", 
+  "trigger_cmd",   "trnm",          "tridxby",       "database_kw_opt",
+  "key_opt",       "add_column_fullname",  "kwcolumn_opt",  "create_vtab", 
+  "vtabarglist",   "vtabarg",       "vtabargtoken",  "lp",          
+  "anylist",       "wqlist",      
 };
 #endif /* NDEBUG */
 
@@ -129111,334 +131987,332 @@ static const char *const yyTokenName[] = {
 /* For tracing reduce actions, the names of all rules are required.
 */
 static const char *const yyRuleName[] = {
- /*   0 */ "input ::= cmdlist",
- /*   1 */ "cmdlist ::= cmdlist ecmd",
- /*   2 */ "cmdlist ::= ecmd",
- /*   3 */ "ecmd ::= SEMI",
- /*   4 */ "ecmd ::= explain cmdx SEMI",
- /*   5 */ "explain ::=",
- /*   6 */ "explain ::= EXPLAIN",
- /*   7 */ "explain ::= EXPLAIN QUERY PLAN",
- /*   8 */ "cmdx ::= cmd",
- /*   9 */ "cmd ::= BEGIN transtype trans_opt",
- /*  10 */ "trans_opt ::=",
- /*  11 */ "trans_opt ::= TRANSACTION",
- /*  12 */ "trans_opt ::= TRANSACTION nm",
- /*  13 */ "transtype ::=",
- /*  14 */ "transtype ::= DEFERRED",
- /*  15 */ "transtype ::= IMMEDIATE",
- /*  16 */ "transtype ::= EXCLUSIVE",
- /*  17 */ "cmd ::= COMMIT trans_opt",
- /*  18 */ "cmd ::= END trans_opt",
- /*  19 */ "cmd ::= ROLLBACK trans_opt",
- /*  20 */ "savepoint_opt ::= SAVEPOINT",
- /*  21 */ "savepoint_opt ::=",
- /*  22 */ "cmd ::= SAVEPOINT nm",
- /*  23 */ "cmd ::= RELEASE savepoint_opt nm",
- /*  24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
- /*  25 */ "cmd ::= create_table create_table_args",
- /*  26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
- /*  27 */ "createkw ::= CREATE",
- /*  28 */ "ifnotexists ::=",
- /*  29 */ "ifnotexists ::= IF NOT EXISTS",
- /*  30 */ "temp ::= TEMP",
- /*  31 */ "temp ::=",
- /*  32 */ "create_table_args ::= LP columnlist conslist_opt RP table_options",
- /*  33 */ "create_table_args ::= AS select",
- /*  34 */ "table_options ::=",
- /*  35 */ "table_options ::= WITHOUT nm",
- /*  36 */ "columnlist ::= columnlist COMMA column",
- /*  37 */ "columnlist ::= column",
- /*  38 */ "column ::= columnid type carglist",
- /*  39 */ "columnid ::= nm",
- /*  40 */ "nm ::= ID|INDEXED",
- /*  41 */ "nm ::= STRING",
- /*  42 */ "nm ::= JOIN_KW",
- /*  43 */ "type ::=",
- /*  44 */ "type ::= typetoken",
- /*  45 */ "typetoken ::= typename",
- /*  46 */ "typetoken ::= typename LP signed RP",
- /*  47 */ "typetoken ::= typename LP signed COMMA signed RP",
- /*  48 */ "typename ::= ID|STRING",
- /*  49 */ "typename ::= typename ID|STRING",
- /*  50 */ "signed ::= plus_num",
- /*  51 */ "signed ::= minus_num",
- /*  52 */ "carglist ::= carglist ccons",
- /*  53 */ "carglist ::=",
- /*  54 */ "ccons ::= CONSTRAINT nm",
- /*  55 */ "ccons ::= DEFAULT term",
- /*  56 */ "ccons ::= DEFAULT LP expr RP",
- /*  57 */ "ccons ::= DEFAULT PLUS term",
- /*  58 */ "ccons ::= DEFAULT MINUS term",
- /*  59 */ "ccons ::= DEFAULT ID|INDEXED",
- /*  60 */ "ccons ::= NULL onconf",
- /*  61 */ "ccons ::= NOT NULL onconf",
- /*  62 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /*  63 */ "ccons ::= UNIQUE onconf",
- /*  64 */ "ccons ::= CHECK LP expr RP",
- /*  65 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
- /*  66 */ "ccons ::= defer_subclause",
- /*  67 */ "ccons ::= COLLATE ID|STRING",
- /*  68 */ "autoinc ::=",
- /*  69 */ "autoinc ::= AUTOINCR",
- /*  70 */ "refargs ::=",
- /*  71 */ "refargs ::= refargs refarg",
- /*  72 */ "refarg ::= MATCH nm",
- /*  73 */ "refarg ::= ON INSERT refact",
- /*  74 */ "refarg ::= ON DELETE refact",
- /*  75 */ "refarg ::= ON UPDATE refact",
- /*  76 */ "refact ::= SET NULL",
- /*  77 */ "refact ::= SET DEFAULT",
- /*  78 */ "refact ::= CASCADE",
- /*  79 */ "refact ::= RESTRICT",
- /*  80 */ "refact ::= NO ACTION",
- /*  81 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /*  82 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /*  83 */ "init_deferred_pred_opt ::=",
- /*  84 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /*  85 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /*  86 */ "conslist_opt ::=",
- /*  87 */ "conslist_opt ::= COMMA conslist",
- /*  88 */ "conslist ::= conslist tconscomma tcons",
- /*  89 */ "conslist ::= tcons",
- /*  90 */ "tconscomma ::= COMMA",
- /*  91 */ "tconscomma ::=",
- /*  92 */ "tcons ::= CONSTRAINT nm",
- /*  93 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
- /*  94 */ "tcons ::= UNIQUE LP sortlist RP onconf",
- /*  95 */ "tcons ::= CHECK LP expr RP onconf",
- /*  96 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
- /*  97 */ "defer_subclause_opt ::=",
- /*  98 */ "defer_subclause_opt ::= defer_subclause",
- /*  99 */ "onconf ::=",
- /* 100 */ "onconf ::= ON CONFLICT resolvetype",
- /* 101 */ "orconf ::=",
- /* 102 */ "orconf ::= OR resolvetype",
- /* 103 */ "resolvetype ::= raisetype",
- /* 104 */ "resolvetype ::= IGNORE",
- /* 105 */ "resolvetype ::= REPLACE",
- /* 106 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 107 */ "ifexists ::= IF EXISTS",
- /* 108 */ "ifexists ::=",
- /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
- /* 110 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 111 */ "cmd ::= select",
- /* 112 */ "select ::= with selectnowith",
- /* 113 */ "selectnowith ::= oneselect",
- /* 114 */ "selectnowith ::= selectnowith multiselect_op oneselect",
- /* 115 */ "multiselect_op ::= UNION",
- /* 116 */ "multiselect_op ::= UNION ALL",
- /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 119 */ "oneselect ::= values",
- /* 120 */ "values ::= VALUES LP nexprlist RP",
- /* 121 */ "values ::= values COMMA LP exprlist RP",
- /* 122 */ "distinct ::= DISTINCT",
- /* 123 */ "distinct ::= ALL",
- /* 124 */ "distinct ::=",
- /* 125 */ "sclp ::= selcollist COMMA",
- /* 126 */ "sclp ::=",
- /* 127 */ "selcollist ::= sclp expr as",
- /* 128 */ "selcollist ::= sclp STAR",
- /* 129 */ "selcollist ::= sclp nm DOT STAR",
- /* 130 */ "as ::= AS nm",
- /* 131 */ "as ::= ID|STRING",
- /* 132 */ "as ::=",
- /* 133 */ "from ::=",
- /* 134 */ "from ::= FROM seltablist",
- /* 135 */ "stl_prefix ::= seltablist joinop",
- /* 136 */ "stl_prefix ::=",
- /* 137 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 138 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
- /* 139 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 140 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 141 */ "dbnm ::=",
- /* 142 */ "dbnm ::= DOT nm",
- /* 143 */ "fullname ::= nm dbnm",
- /* 144 */ "joinop ::= COMMA|JOIN",
- /* 145 */ "joinop ::= JOIN_KW JOIN",
- /* 146 */ "joinop ::= JOIN_KW nm JOIN",
- /* 147 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 148 */ "on_opt ::= ON expr",
- /* 149 */ "on_opt ::=",
- /* 150 */ "indexed_opt ::=",
- /* 151 */ "indexed_opt ::= INDEXED BY nm",
- /* 152 */ "indexed_opt ::= NOT INDEXED",
- /* 153 */ "using_opt ::= USING LP idlist RP",
- /* 154 */ "using_opt ::=",
- /* 155 */ "orderby_opt ::=",
- /* 156 */ "orderby_opt ::= ORDER BY sortlist",
- /* 157 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 158 */ "sortlist ::= expr sortorder",
- /* 159 */ "sortorder ::= ASC",
- /* 160 */ "sortorder ::= DESC",
- /* 161 */ "sortorder ::=",
- /* 162 */ "groupby_opt ::=",
- /* 163 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 164 */ "having_opt ::=",
- /* 165 */ "having_opt ::= HAVING expr",
- /* 166 */ "limit_opt ::=",
- /* 167 */ "limit_opt ::= LIMIT expr",
- /* 168 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 169 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 170 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt orderby_opt limit_opt",
- /* 171 */ "where_opt ::=",
- /* 172 */ "where_opt ::= WHERE expr",
- /* 173 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt orderby_opt limit_opt",
- /* 174 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 175 */ "setlist ::= nm EQ expr",
- /* 176 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
- /* 177 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
- /* 178 */ "insert_cmd ::= INSERT orconf",
- /* 179 */ "insert_cmd ::= REPLACE",
- /* 180 */ "idlist_opt ::=",
- /* 181 */ "idlist_opt ::= LP idlist RP",
- /* 182 */ "idlist ::= idlist COMMA nm",
- /* 183 */ "idlist ::= nm",
- /* 184 */ "expr ::= term",
- /* 185 */ "expr ::= LP expr RP",
- /* 186 */ "term ::= NULL",
- /* 187 */ "expr ::= ID|INDEXED",
- /* 188 */ "expr ::= JOIN_KW",
- /* 189 */ "expr ::= nm DOT nm",
- /* 190 */ "expr ::= nm DOT nm DOT nm",
- /* 191 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 192 */ "term ::= STRING",
- /* 193 */ "expr ::= VARIABLE",
- /* 194 */ "expr ::= expr COLLATE ID|STRING",
- /* 195 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 196 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
- /* 197 */ "expr ::= ID|INDEXED LP STAR RP",
- /* 198 */ "term ::= CTIME_KW",
- /* 199 */ "expr ::= expr AND expr",
- /* 200 */ "expr ::= expr OR expr",
- /* 201 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 202 */ "expr ::= expr EQ|NE expr",
- /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 204 */ "expr ::= expr PLUS|MINUS expr",
- /* 205 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 206 */ "expr ::= expr CONCAT expr",
- /* 207 */ "likeop ::= LIKE_KW|MATCH",
- /* 208 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 209 */ "expr ::= expr likeop expr",
- /* 210 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 211 */ "expr ::= expr ISNULL|NOTNULL",
- /* 212 */ "expr ::= expr NOT NULL",
- /* 213 */ "expr ::= expr IS expr",
- /* 214 */ "expr ::= expr IS NOT expr",
- /* 215 */ "expr ::= NOT expr",
- /* 216 */ "expr ::= BITNOT expr",
- /* 217 */ "expr ::= MINUS expr",
- /* 218 */ "expr ::= PLUS expr",
- /* 219 */ "between_op ::= BETWEEN",
- /* 220 */ "between_op ::= NOT BETWEEN",
- /* 221 */ "expr ::= expr between_op expr AND expr",
- /* 222 */ "in_op ::= IN",
- /* 223 */ "in_op ::= NOT IN",
- /* 224 */ "expr ::= expr in_op LP exprlist RP",
- /* 225 */ "expr ::= LP select RP",
- /* 226 */ "expr ::= expr in_op LP select RP",
- /* 227 */ "expr ::= expr in_op nm dbnm",
- /* 228 */ "expr ::= EXISTS LP select RP",
- /* 229 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 230 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 231 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 232 */ "case_else ::= ELSE expr",
- /* 233 */ "case_else ::=",
- /* 234 */ "case_operand ::= expr",
- /* 235 */ "case_operand ::=",
- /* 236 */ "exprlist ::= nexprlist",
- /* 237 */ "exprlist ::=",
- /* 238 */ "nexprlist ::= nexprlist COMMA expr",
- /* 239 */ "nexprlist ::= expr",
- /* 240 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 241 */ "uniqueflag ::= UNIQUE",
- /* 242 */ "uniqueflag ::=",
- /* 243 */ "eidlist_opt ::=",
- /* 244 */ "eidlist_opt ::= LP eidlist RP",
- /* 245 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 246 */ "eidlist ::= nm collate sortorder",
- /* 247 */ "collate ::=",
- /* 248 */ "collate ::= COLLATE ID|STRING",
- /* 249 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 250 */ "cmd ::= VACUUM",
- /* 251 */ "cmd ::= VACUUM nm",
- /* 252 */ "cmd ::= PRAGMA nm dbnm",
- /* 253 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 254 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 255 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 256 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 257 */ "nmnum ::= plus_num",
- /* 258 */ "nmnum ::= nm",
- /* 259 */ "nmnum ::= ON",
- /* 260 */ "nmnum ::= DELETE",
- /* 261 */ "nmnum ::= DEFAULT",
- /* 262 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 263 */ "plus_num ::= INTEGER|FLOAT",
- /* 264 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 265 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 266 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 267 */ "trigger_time ::= BEFORE",
- /* 268 */ "trigger_time ::= AFTER",
- /* 269 */ "trigger_time ::= INSTEAD OF",
- /* 270 */ "trigger_time ::=",
- /* 271 */ "trigger_event ::= DELETE|INSERT",
- /* 272 */ "trigger_event ::= UPDATE",
- /* 273 */ "trigger_event ::= UPDATE OF idlist",
- /* 274 */ "foreach_clause ::=",
- /* 275 */ "foreach_clause ::= FOR EACH ROW",
- /* 276 */ "when_clause ::=",
- /* 277 */ "when_clause ::= WHEN expr",
- /* 278 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 279 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 280 */ "trnm ::= nm",
- /* 281 */ "trnm ::= nm DOT nm",
- /* 282 */ "tridxby ::=",
- /* 283 */ "tridxby ::= INDEXED BY nm",
- /* 284 */ "tridxby ::= NOT INDEXED",
- /* 285 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 286 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
- /* 287 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 288 */ "trigger_cmd ::= select",
- /* 289 */ "expr ::= RAISE LP IGNORE RP",
- /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 291 */ "raisetype ::= ROLLBACK",
- /* 292 */ "raisetype ::= ABORT",
- /* 293 */ "raisetype ::= FAIL",
- /* 294 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 295 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 296 */ "cmd ::= DETACH database_kw_opt expr",
- /* 297 */ "key_opt ::=",
- /* 298 */ "key_opt ::= KEY expr",
- /* 299 */ "database_kw_opt ::= DATABASE",
- /* 300 */ "database_kw_opt ::=",
- /* 301 */ "cmd ::= REINDEX",
- /* 302 */ "cmd ::= REINDEX nm dbnm",
- /* 303 */ "cmd ::= ANALYZE",
- /* 304 */ "cmd ::= ANALYZE nm dbnm",
- /* 305 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 306 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 307 */ "add_column_fullname ::= fullname",
- /* 308 */ "kwcolumn_opt ::=",
- /* 309 */ "kwcolumn_opt ::= COLUMNKW",
- /* 310 */ "cmd ::= create_vtab",
- /* 311 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 312 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 313 */ "vtabarglist ::= vtabarg",
- /* 314 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 315 */ "vtabarg ::=",
- /* 316 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 317 */ "vtabargtoken ::= ANY",
- /* 318 */ "vtabargtoken ::= lp anylist RP",
- /* 319 */ "lp ::= LP",
- /* 320 */ "anylist ::=",
- /* 321 */ "anylist ::= anylist LP anylist RP",
- /* 322 */ "anylist ::= anylist ANY",
- /* 323 */ "with ::=",
- /* 324 */ "with ::= WITH wqlist",
- /* 325 */ "with ::= WITH RECURSIVE wqlist",
- /* 326 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 327 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /*   0 */ "explain ::= EXPLAIN",
+ /*   1 */ "explain ::= EXPLAIN QUERY PLAN",
+ /*   2 */ "cmdx ::= cmd",
+ /*   3 */ "cmd ::= BEGIN transtype trans_opt",
+ /*   4 */ "transtype ::=",
+ /*   5 */ "transtype ::= DEFERRED",
+ /*   6 */ "transtype ::= IMMEDIATE",
+ /*   7 */ "transtype ::= EXCLUSIVE",
+ /*   8 */ "cmd ::= COMMIT trans_opt",
+ /*   9 */ "cmd ::= END trans_opt",
+ /*  10 */ "cmd ::= ROLLBACK trans_opt",
+ /*  11 */ "cmd ::= SAVEPOINT nm",
+ /*  12 */ "cmd ::= RELEASE savepoint_opt nm",
+ /*  13 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
+ /*  14 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
+ /*  15 */ "createkw ::= CREATE",
+ /*  16 */ "ifnotexists ::=",
+ /*  17 */ "ifnotexists ::= IF NOT EXISTS",
+ /*  18 */ "temp ::= TEMP",
+ /*  19 */ "temp ::=",
+ /*  20 */ "create_table_args ::= LP columnlist conslist_opt RP table_options",
+ /*  21 */ "create_table_args ::= AS select",
+ /*  22 */ "table_options ::=",
+ /*  23 */ "table_options ::= WITHOUT nm",
+ /*  24 */ "columnname ::= nm typetoken",
+ /*  25 */ "typetoken ::=",
+ /*  26 */ "typetoken ::= typename LP signed RP",
+ /*  27 */ "typetoken ::= typename LP signed COMMA signed RP",
+ /*  28 */ "typename ::= typename ID|STRING",
+ /*  29 */ "ccons ::= CONSTRAINT nm",
+ /*  30 */ "ccons ::= DEFAULT term",
+ /*  31 */ "ccons ::= DEFAULT LP expr RP",
+ /*  32 */ "ccons ::= DEFAULT PLUS term",
+ /*  33 */ "ccons ::= DEFAULT MINUS term",
+ /*  34 */ "ccons ::= DEFAULT ID|INDEXED",
+ /*  35 */ "ccons ::= NOT NULL onconf",
+ /*  36 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /*  37 */ "ccons ::= UNIQUE onconf",
+ /*  38 */ "ccons ::= CHECK LP expr RP",
+ /*  39 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
+ /*  40 */ "ccons ::= defer_subclause",
+ /*  41 */ "ccons ::= COLLATE ID|STRING",
+ /*  42 */ "autoinc ::=",
+ /*  43 */ "autoinc ::= AUTOINCR",
+ /*  44 */ "refargs ::=",
+ /*  45 */ "refargs ::= refargs refarg",
+ /*  46 */ "refarg ::= MATCH nm",
+ /*  47 */ "refarg ::= ON INSERT refact",
+ /*  48 */ "refarg ::= ON DELETE refact",
+ /*  49 */ "refarg ::= ON UPDATE refact",
+ /*  50 */ "refact ::= SET NULL",
+ /*  51 */ "refact ::= SET DEFAULT",
+ /*  52 */ "refact ::= CASCADE",
+ /*  53 */ "refact ::= RESTRICT",
+ /*  54 */ "refact ::= NO ACTION",
+ /*  55 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /*  56 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /*  57 */ "init_deferred_pred_opt ::=",
+ /*  58 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /*  59 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /*  60 */ "conslist_opt ::=",
+ /*  61 */ "tconscomma ::= COMMA",
+ /*  62 */ "tcons ::= CONSTRAINT nm",
+ /*  63 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+ /*  64 */ "tcons ::= UNIQUE LP sortlist RP onconf",
+ /*  65 */ "tcons ::= CHECK LP expr RP onconf",
+ /*  66 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
+ /*  67 */ "defer_subclause_opt ::=",
+ /*  68 */ "onconf ::=",
+ /*  69 */ "onconf ::= ON CONFLICT resolvetype",
+ /*  70 */ "orconf ::=",
+ /*  71 */ "orconf ::= OR resolvetype",
+ /*  72 */ "resolvetype ::= IGNORE",
+ /*  73 */ "resolvetype ::= REPLACE",
+ /*  74 */ "cmd ::= DROP TABLE ifexists fullname",
+ /*  75 */ "ifexists ::= IF EXISTS",
+ /*  76 */ "ifexists ::=",
+ /*  77 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
+ /*  78 */ "cmd ::= DROP VIEW ifexists fullname",
+ /*  79 */ "cmd ::= select",
+ /*  80 */ "select ::= with selectnowith",
+ /*  81 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+ /*  82 */ "multiselect_op ::= UNION",
+ /*  83 */ "multiselect_op ::= UNION ALL",
+ /*  84 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /*  85 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /*  86 */ "values ::= VALUES LP nexprlist RP",
+ /*  87 */ "values ::= values COMMA LP exprlist RP",
+ /*  88 */ "distinct ::= DISTINCT",
+ /*  89 */ "distinct ::= ALL",
+ /*  90 */ "distinct ::=",
+ /*  91 */ "sclp ::=",
+ /*  92 */ "selcollist ::= sclp expr as",
+ /*  93 */ "selcollist ::= sclp STAR",
+ /*  94 */ "selcollist ::= sclp nm DOT STAR",
+ /*  95 */ "as ::= AS nm",
+ /*  96 */ "as ::=",
+ /*  97 */ "from ::=",
+ /*  98 */ "from ::= FROM seltablist",
+ /*  99 */ "stl_prefix ::= seltablist joinop",
+ /* 100 */ "stl_prefix ::=",
+ /* 101 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 102 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 103 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 104 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 105 */ "dbnm ::=",
+ /* 106 */ "dbnm ::= DOT nm",
+ /* 107 */ "fullname ::= nm dbnm",
+ /* 108 */ "joinop ::= COMMA|JOIN",
+ /* 109 */ "joinop ::= JOIN_KW JOIN",
+ /* 110 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 111 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 112 */ "on_opt ::= ON expr",
+ /* 113 */ "on_opt ::=",
+ /* 114 */ "indexed_opt ::=",
+ /* 115 */ "indexed_opt ::= INDEXED BY nm",
+ /* 116 */ "indexed_opt ::= NOT INDEXED",
+ /* 117 */ "using_opt ::= USING LP idlist RP",
+ /* 118 */ "using_opt ::=",
+ /* 119 */ "orderby_opt ::=",
+ /* 120 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 121 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 122 */ "sortlist ::= expr sortorder",
+ /* 123 */ "sortorder ::= ASC",
+ /* 124 */ "sortorder ::= DESC",
+ /* 125 */ "sortorder ::=",
+ /* 126 */ "groupby_opt ::=",
+ /* 127 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 128 */ "having_opt ::=",
+ /* 129 */ "having_opt ::= HAVING expr",
+ /* 130 */ "limit_opt ::=",
+ /* 131 */ "limit_opt ::= LIMIT expr",
+ /* 132 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 133 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 134 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt orderby_opt limit_opt",
+ /* 135 */ "where_opt ::=",
+ /* 136 */ "where_opt ::= WHERE expr",
+ /* 137 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt orderby_opt limit_opt",
+ /* 138 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 139 */ "setlist ::= nm EQ expr",
+ /* 140 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
+ /* 141 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
+ /* 142 */ "insert_cmd ::= INSERT orconf",
+ /* 143 */ "insert_cmd ::= REPLACE",
+ /* 144 */ "idlist_opt ::=",
+ /* 145 */ "idlist_opt ::= LP idlist RP",
+ /* 146 */ "idlist ::= idlist COMMA nm",
+ /* 147 */ "idlist ::= nm",
+ /* 148 */ "expr ::= LP expr RP",
+ /* 149 */ "term ::= NULL",
+ /* 150 */ "expr ::= ID|INDEXED",
+ /* 151 */ "expr ::= JOIN_KW",
+ /* 152 */ "expr ::= nm DOT nm",
+ /* 153 */ "expr ::= nm DOT nm DOT nm",
+ /* 154 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 155 */ "term ::= STRING",
+ /* 156 */ "expr ::= VARIABLE",
+ /* 157 */ "expr ::= expr COLLATE ID|STRING",
+ /* 158 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 159 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 160 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 161 */ "term ::= CTIME_KW",
+ /* 162 */ "expr ::= expr AND expr",
+ /* 163 */ "expr ::= expr OR expr",
+ /* 164 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 165 */ "expr ::= expr EQ|NE expr",
+ /* 166 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 167 */ "expr ::= expr PLUS|MINUS expr",
+ /* 168 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 169 */ "expr ::= expr CONCAT expr",
+ /* 170 */ "likeop ::= LIKE_KW|MATCH",
+ /* 171 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 172 */ "expr ::= expr likeop expr",
+ /* 173 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 174 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 175 */ "expr ::= expr NOT NULL",
+ /* 176 */ "expr ::= expr IS expr",
+ /* 177 */ "expr ::= expr IS NOT expr",
+ /* 178 */ "expr ::= NOT expr",
+ /* 179 */ "expr ::= BITNOT expr",
+ /* 180 */ "expr ::= MINUS expr",
+ /* 181 */ "expr ::= PLUS expr",
+ /* 182 */ "between_op ::= BETWEEN",
+ /* 183 */ "between_op ::= NOT BETWEEN",
+ /* 184 */ "expr ::= expr between_op expr AND expr",
+ /* 185 */ "in_op ::= IN",
+ /* 186 */ "in_op ::= NOT IN",
+ /* 187 */ "expr ::= expr in_op LP exprlist RP",
+ /* 188 */ "expr ::= LP select RP",
+ /* 189 */ "expr ::= expr in_op LP select RP",
+ /* 190 */ "expr ::= expr in_op nm dbnm",
+ /* 191 */ "expr ::= EXISTS LP select RP",
+ /* 192 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 193 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 194 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 195 */ "case_else ::= ELSE expr",
+ /* 196 */ "case_else ::=",
+ /* 197 */ "case_operand ::= expr",
+ /* 198 */ "case_operand ::=",
+ /* 199 */ "exprlist ::=",
+ /* 200 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 201 */ "nexprlist ::= expr",
+ /* 202 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 203 */ "uniqueflag ::= UNIQUE",
+ /* 204 */ "uniqueflag ::=",
+ /* 205 */ "eidlist_opt ::=",
+ /* 206 */ "eidlist_opt ::= LP eidlist RP",
+ /* 207 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 208 */ "eidlist ::= nm collate sortorder",
+ /* 209 */ "collate ::=",
+ /* 210 */ "collate ::= COLLATE ID|STRING",
+ /* 211 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 212 */ "cmd ::= VACUUM",
+ /* 213 */ "cmd ::= VACUUM nm",
+ /* 214 */ "cmd ::= PRAGMA nm dbnm",
+ /* 215 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 216 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 217 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 218 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 219 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 220 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 221 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 222 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 223 */ "trigger_time ::= BEFORE",
+ /* 224 */ "trigger_time ::= AFTER",
+ /* 225 */ "trigger_time ::= INSTEAD OF",
+ /* 226 */ "trigger_time ::=",
+ /* 227 */ "trigger_event ::= DELETE|INSERT",
+ /* 228 */ "trigger_event ::= UPDATE",
+ /* 229 */ "trigger_event ::= UPDATE OF idlist",
+ /* 230 */ "when_clause ::=",
+ /* 231 */ "when_clause ::= WHEN expr",
+ /* 232 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 233 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 234 */ "trnm ::= nm DOT nm",
+ /* 235 */ "tridxby ::= INDEXED BY nm",
+ /* 236 */ "tridxby ::= NOT INDEXED",
+ /* 237 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 238 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
+ /* 239 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 240 */ "trigger_cmd ::= select",
+ /* 241 */ "expr ::= RAISE LP IGNORE RP",
+ /* 242 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 243 */ "raisetype ::= ROLLBACK",
+ /* 244 */ "raisetype ::= ABORT",
+ /* 245 */ "raisetype ::= FAIL",
+ /* 246 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 247 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 248 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 249 */ "key_opt ::=",
+ /* 250 */ "key_opt ::= KEY expr",
+ /* 251 */ "cmd ::= REINDEX",
+ /* 252 */ "cmd ::= REINDEX nm dbnm",
+ /* 253 */ "cmd ::= ANALYZE",
+ /* 254 */ "cmd ::= ANALYZE nm dbnm",
+ /* 255 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 256 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 257 */ "add_column_fullname ::= fullname",
+ /* 258 */ "cmd ::= create_vtab",
+ /* 259 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 260 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 261 */ "vtabarg ::=",
+ /* 262 */ "vtabargtoken ::= ANY",
+ /* 263 */ "vtabargtoken ::= lp anylist RP",
+ /* 264 */ "lp ::= LP",
+ /* 265 */ "with ::=",
+ /* 266 */ "with ::= WITH wqlist",
+ /* 267 */ "with ::= WITH RECURSIVE wqlist",
+ /* 268 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 269 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 270 */ "input ::= cmdlist",
+ /* 271 */ "cmdlist ::= cmdlist ecmd",
+ /* 272 */ "cmdlist ::= ecmd",
+ /* 273 */ "ecmd ::= SEMI",
+ /* 274 */ "ecmd ::= explain cmdx SEMI",
+ /* 275 */ "explain ::=",
+ /* 276 */ "trans_opt ::=",
+ /* 277 */ "trans_opt ::= TRANSACTION",
+ /* 278 */ "trans_opt ::= TRANSACTION nm",
+ /* 279 */ "savepoint_opt ::= SAVEPOINT",
+ /* 280 */ "savepoint_opt ::=",
+ /* 281 */ "cmd ::= create_table create_table_args",
+ /* 282 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 283 */ "columnlist ::= columnname carglist",
+ /* 284 */ "nm ::= ID|INDEXED",
+ /* 285 */ "nm ::= STRING",
+ /* 286 */ "nm ::= JOIN_KW",
+ /* 287 */ "typetoken ::= typename",
+ /* 288 */ "typename ::= ID|STRING",
+ /* 289 */ "signed ::= plus_num",
+ /* 290 */ "signed ::= minus_num",
+ /* 291 */ "carglist ::= carglist ccons",
+ /* 292 */ "carglist ::=",
+ /* 293 */ "ccons ::= NULL onconf",
+ /* 294 */ "conslist_opt ::= COMMA conslist",
+ /* 295 */ "conslist ::= conslist tconscomma tcons",
+ /* 296 */ "conslist ::= tcons",
+ /* 297 */ "tconscomma ::=",
+ /* 298 */ "defer_subclause_opt ::= defer_subclause",
+ /* 299 */ "resolvetype ::= raisetype",
+ /* 300 */ "selectnowith ::= oneselect",
+ /* 301 */ "oneselect ::= values",
+ /* 302 */ "sclp ::= selcollist COMMA",
+ /* 303 */ "as ::= ID|STRING",
+ /* 304 */ "expr ::= term",
+ /* 305 */ "exprlist ::= nexprlist",
+ /* 306 */ "nmnum ::= plus_num",
+ /* 307 */ "nmnum ::= nm",
+ /* 308 */ "nmnum ::= ON",
+ /* 309 */ "nmnum ::= DELETE",
+ /* 310 */ "nmnum ::= DEFAULT",
+ /* 311 */ "plus_num ::= INTEGER|FLOAT",
+ /* 312 */ "foreach_clause ::=",
+ /* 313 */ "foreach_clause ::= FOR EACH ROW",
+ /* 314 */ "trnm ::= nm",
+ /* 315 */ "tridxby ::=",
+ /* 316 */ "database_kw_opt ::= DATABASE",
+ /* 317 */ "database_kw_opt ::=",
+ /* 318 */ "kwcolumn_opt ::=",
+ /* 319 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 320 */ "vtabarglist ::= vtabarg",
+ /* 321 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 322 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 323 */ "anylist ::=",
+ /* 324 */ "anylist ::= anylist LP anylist RP",
+ /* 325 */ "anylist ::= anylist ANY",
 };
 #endif /* NDEBUG */
 
@@ -129530,75 +132404,75 @@ static void yy_destructor(
     */
 /********* Begin destructor definitions ***************************************/
     case 163: /* select */
-    case 196: /* selectnowith */
-    case 197: /* oneselect */
-    case 208: /* values */
+    case 194: /* selectnowith */
+    case 195: /* oneselect */
+    case 206: /* values */
 {
-sqlite3SelectDelete(pParse->db, (yypminor->yy387));
+sqlite3SelectDelete(pParse->db, (yypminor->yy159));
 }
       break;
-    case 174: /* term */
-    case 175: /* expr */
+    case 172: /* term */
+    case 173: /* expr */
 {
-sqlite3ExprDelete(pParse->db, (yypminor->yy118).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr);
 }
       break;
-    case 179: /* eidlist_opt */
-    case 188: /* sortlist */
-    case 189: /* eidlist */
-    case 201: /* selcollist */
-    case 204: /* groupby_opt */
-    case 206: /* orderby_opt */
-    case 209: /* nexprlist */
-    case 210: /* exprlist */
-    case 211: /* sclp */
-    case 220: /* setlist */
-    case 227: /* case_exprlist */
+    case 177: /* eidlist_opt */
+    case 186: /* sortlist */
+    case 187: /* eidlist */
+    case 199: /* selcollist */
+    case 202: /* groupby_opt */
+    case 204: /* orderby_opt */
+    case 207: /* nexprlist */
+    case 208: /* exprlist */
+    case 209: /* sclp */
+    case 218: /* setlist */
+    case 225: /* case_exprlist */
 {
-sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy442));
 }
       break;
-    case 195: /* fullname */
-    case 202: /* from */
-    case 213: /* seltablist */
-    case 214: /* stl_prefix */
+    case 193: /* fullname */
+    case 200: /* from */
+    case 211: /* seltablist */
+    case 212: /* stl_prefix */
 {
-sqlite3SrcListDelete(pParse->db, (yypminor->yy259));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy347));
 }
       break;
-    case 198: /* with */
-    case 251: /* wqlist */
+    case 196: /* with */
+    case 249: /* wqlist */
 {
-sqlite3WithDelete(pParse->db, (yypminor->yy451));
+sqlite3WithDelete(pParse->db, (yypminor->yy331));
 }
       break;
-    case 203: /* where_opt */
-    case 205: /* having_opt */
-    case 217: /* on_opt */
-    case 226: /* case_operand */
-    case 228: /* case_else */
-    case 237: /* when_clause */
-    case 242: /* key_opt */
+    case 201: /* where_opt */
+    case 203: /* having_opt */
+    case 215: /* on_opt */
+    case 224: /* case_operand */
+    case 226: /* case_else */
+    case 235: /* when_clause */
+    case 240: /* key_opt */
 {
-sqlite3ExprDelete(pParse->db, (yypminor->yy314));
+sqlite3ExprDelete(pParse->db, (yypminor->yy122));
 }
       break;
-    case 218: /* using_opt */
-    case 219: /* idlist */
-    case 222: /* idlist_opt */
+    case 216: /* using_opt */
+    case 217: /* idlist */
+    case 220: /* idlist_opt */
 {
-sqlite3IdListDelete(pParse->db, (yypminor->yy384));
+sqlite3IdListDelete(pParse->db, (yypminor->yy180));
 }
       break;
-    case 233: /* trigger_cmd_list */
-    case 238: /* trigger_cmd */
+    case 231: /* trigger_cmd_list */
+    case 236: /* trigger_cmd */
 {
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy327));
 }
       break;
-    case 235: /* trigger_event */
+    case 233: /* trigger_event */
 {
-sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy410).b);
 }
       break;
 /********* End destructor definitions *****************************************/
@@ -129663,7 +132537,7 @@ SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
 ** Find the appropriate action for a parser given the terminal
 ** look-ahead token iLookAhead.
 */
-static int yy_find_shift_action(
+static unsigned int yy_find_shift_action(
   yyParser *pParser,        /* The parser */
   YYCODETYPE iLookAhead     /* The look-ahead token */
 ){
@@ -129759,7 +132633,7 @@ static int yy_find_reduce_action(
 /*
 ** The following routine is called if the stack overflows.
 */
-static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
+static void yyStackOverflow(yyParser *yypParser){
    sqlite3ParserARG_FETCH;
    yypParser->yyidx--;
 #ifndef NDEBUG
@@ -129772,7 +132646,6 @@ static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
    ** stack every overflows */
 /******** Begin %stack_overflow code ******************************************/
 
-  UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
   sqlite3ErrorMsg(pParse, "parser stack overflow");
 /******** End %stack_overflow code ********************************************/
    sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
@@ -129805,7 +132678,7 @@ static void yy_shift(
   yyParser *yypParser,          /* The parser to be shifted */
   int yyNewState,               /* The new state to shift in */
   int yyMajor,                  /* The major token to shift in */
-  YYMINORTYPE *yypMinor         /* Pointer to the minor token to shift in */
+  sqlite3ParserTOKENTYPE yyMinor        /* The minor token to shift in */
 ){
   yyStackEntry *yytos;
   yypParser->yyidx++;
@@ -129816,14 +132689,14 @@ static void yy_shift(
 #endif
 #if YYSTACKDEPTH>0 
   if( yypParser->yyidx>=YYSTACKDEPTH ){
-    yyStackOverflow(yypParser, yypMinor);
+    yyStackOverflow(yypParser);
     return;
   }
 #else
   if( yypParser->yyidx>=yypParser->yystksz ){
     yyGrowStack(yypParser);
     if( yypParser->yyidx>=yypParser->yystksz ){
-      yyStackOverflow(yypParser, yypMinor);
+      yyStackOverflow(yypParser);
       return;
     }
   }
@@ -129831,7 +132704,7 @@ static void yy_shift(
   yytos = &yypParser->yystack[yypParser->yyidx];
   yytos->stateno = (YYACTIONTYPE)yyNewState;
   yytos->major = (YYCODETYPE)yyMajor;
-  yytos->minor = *yypMinor;
+  yytos->minor.yy0 = yyMinor;
   yyTraceShift(yypParser, yyNewState);
 }
 
@@ -129842,19 +132715,10 @@ static const struct {
   YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
   unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
 } yyRuleInfo[] = {
-  { 144, 1 },
-  { 145, 2 },
-  { 145, 1 },
-  { 146, 1 },
-  { 146, 3 },
-  { 147, 0 },
   { 147, 1 },
   { 147, 3 },
   { 148, 1 },
   { 149, 3 },
-  { 151, 0 },
-  { 151, 1 },
-  { 151, 2 },
   { 150, 0 },
   { 150, 1 },
   { 150, 1 },
@@ -129862,12 +132726,9 @@ static const struct {
   { 149, 2 },
   { 149, 2 },
   { 149, 2 },
-  { 153, 1 },
-  { 153, 0 },
   { 149, 2 },
   { 149, 3 },
   { 149, 5 },
-  { 149, 2 },
   { 154, 6 },
   { 156, 1 },
   { 158, 0 },
@@ -129878,219 +132739,193 @@ static const struct {
   { 155, 2 },
   { 162, 0 },
   { 162, 2 },
-  { 160, 3 },
-  { 160, 1 },
-  { 164, 3 },
-  { 165, 1 },
-  { 152, 1 },
-  { 152, 1 },
-  { 152, 1 },
+  { 164, 2 },
   { 166, 0 },
-  { 166, 1 },
-  { 168, 1 },
-  { 168, 4 },
-  { 168, 6 },
-  { 169, 1 },
-  { 169, 2 },
-  { 170, 1 },
-  { 170, 1 },
+  { 166, 4 },
+  { 166, 6 },
   { 167, 2 },
-  { 167, 0 },
-  { 173, 2 },
-  { 173, 2 },
-  { 173, 4 },
-  { 173, 3 },
-  { 173, 3 },
-  { 173, 2 },
-  { 173, 2 },
-  { 173, 3 },
-  { 173, 5 },
-  { 173, 2 },
-  { 173, 4 },
-  { 173, 4 },
-  { 173, 1 },
-  { 173, 2 },
+  { 171, 2 },
+  { 171, 2 },
+  { 171, 4 },
+  { 171, 3 },
+  { 171, 3 },
+  { 171, 2 },
+  { 171, 3 },
+  { 171, 5 },
+  { 171, 2 },
+  { 171, 4 },
+  { 171, 4 },
+  { 171, 1 },
+  { 171, 2 },
+  { 176, 0 },
+  { 176, 1 },
   { 178, 0 },
-  { 178, 1 },
-  { 180, 0 },
+  { 178, 2 },
   { 180, 2 },
-  { 182, 2 },
-  { 182, 3 },
-  { 182, 3 },
-  { 182, 3 },
-  { 183, 2 },
-  { 183, 2 },
-  { 183, 1 },
-  { 183, 1 },
-  { 183, 2 },
-  { 181, 3 },
+  { 180, 3 },
+  { 180, 3 },
+  { 180, 3 },
   { 181, 2 },
-  { 184, 0 },
-  { 184, 2 },
-  { 184, 2 },
+  { 181, 2 },
+  { 181, 1 },
+  { 181, 1 },
+  { 181, 2 },
+  { 179, 3 },
+  { 179, 2 },
+  { 182, 0 },
+  { 182, 2 },
+  { 182, 2 },
   { 161, 0 },
-  { 161, 2 },
-  { 185, 3 },
-  { 185, 1 },
-  { 186, 1 },
-  { 186, 0 },
-  { 187, 2 },
-  { 187, 7 },
-  { 187, 5 },
-  { 187, 5 },
-  { 187, 10 },
-  { 190, 0 },
+  { 184, 1 },
+  { 185, 2 },
+  { 185, 7 },
+  { 185, 5 },
+  { 185, 5 },
+  { 185, 10 },
+  { 188, 0 },
+  { 174, 0 },
+  { 174, 3 },
+  { 189, 0 },
+  { 189, 2 },
+  { 190, 1 },
   { 190, 1 },
-  { 176, 0 },
-  { 176, 3 },
-  { 191, 0 },
-  { 191, 2 },
-  { 192, 1 },
-  { 192, 1 },
-  { 192, 1 },
   { 149, 4 },
-  { 194, 2 },
-  { 194, 0 },
+  { 192, 2 },
+  { 192, 0 },
   { 149, 9 },
   { 149, 4 },
   { 149, 1 },
   { 163, 2 },
-  { 196, 1 },
-  { 196, 3 },
-  { 199, 1 },
-  { 199, 2 },
-  { 199, 1 },
-  { 197, 9 },
+  { 194, 3 },
   { 197, 1 },
-  { 208, 4 },
-  { 208, 5 },
-  { 200, 1 },
-  { 200, 1 },
+  { 197, 2 },
+  { 197, 1 },
+  { 195, 9 },
+  { 206, 4 },
+  { 206, 5 },
+  { 198, 1 },
+  { 198, 1 },
+  { 198, 0 },
+  { 209, 0 },
+  { 199, 3 },
+  { 199, 2 },
+  { 199, 4 },
+  { 210, 2 },
+  { 210, 0 },
   { 200, 0 },
-  { 211, 2 },
-  { 211, 0 },
-  { 201, 3 },
-  { 201, 2 },
-  { 201, 4 },
+  { 200, 2 },
   { 212, 2 },
-  { 212, 1 },
   { 212, 0 },
-  { 202, 0 },
-  { 202, 2 },
-  { 214, 2 },
-  { 214, 0 },
-  { 213, 7 },
-  { 213, 9 },
-  { 213, 7 },
-  { 213, 7 },
+  { 211, 7 },
+  { 211, 9 },
+  { 211, 7 },
+  { 211, 7 },
   { 159, 0 },
   { 159, 2 },
-  { 195, 2 },
-  { 215, 1 },
+  { 193, 2 },
+  { 213, 1 },
+  { 213, 2 },
+  { 213, 3 },
+  { 213, 4 },
   { 215, 2 },
-  { 215, 3 },
-  { 215, 4 },
-  { 217, 2 },
-  { 217, 0 },
+  { 215, 0 },
+  { 214, 0 },
+  { 214, 3 },
+  { 214, 2 },
+  { 216, 4 },
   { 216, 0 },
-  { 216, 3 },
-  { 216, 2 },
-  { 218, 4 },
-  { 218, 0 },
-  { 206, 0 },
-  { 206, 3 },
-  { 188, 4 },
-  { 188, 2 },
-  { 177, 1 },
-  { 177, 1 },
-  { 177, 0 },
   { 204, 0 },
   { 204, 3 },
+  { 186, 4 },
+  { 186, 2 },
+  { 175, 1 },
+  { 175, 1 },
+  { 175, 0 },
+  { 202, 0 },
+  { 202, 3 },
+  { 203, 0 },
+  { 203, 2 },
   { 205, 0 },
   { 205, 2 },
-  { 207, 0 },
-  { 207, 2 },
-  { 207, 4 },
-  { 207, 4 },
+  { 205, 4 },
+  { 205, 4 },
   { 149, 8 },
-  { 203, 0 },
-  { 203, 2 },
+  { 201, 0 },
+  { 201, 2 },
   { 149, 10 },
-  { 220, 5 },
-  { 220, 3 },
+  { 218, 5 },
+  { 218, 3 },
   { 149, 6 },
   { 149, 7 },
-  { 221, 2 },
-  { 221, 1 },
-  { 222, 0 },
-  { 222, 3 },
-  { 219, 3 },
+  { 219, 2 },
   { 219, 1 },
-  { 175, 1 },
-  { 175, 3 },
-  { 174, 1 },
-  { 175, 1 },
-  { 175, 1 },
-  { 175, 3 },
-  { 175, 5 },
-  { 174, 1 },
-  { 174, 1 },
-  { 175, 1 },
-  { 175, 3 },
-  { 175, 6 },
-  { 175, 5 },
-  { 175, 4 },
-  { 174, 1 },
-  { 175, 3 },
-  { 175, 3 },
-  { 175, 3 },
-  { 175, 3 },
-  { 175, 3 },
-  { 175, 3 },
-  { 175, 3 },
-  { 175, 3 },
+  { 220, 0 },
+  { 220, 3 },
+  { 217, 3 },
+  { 217, 1 },
+  { 173, 3 },
+  { 172, 1 },
+  { 173, 1 },
+  { 173, 1 },
+  { 173, 3 },
+  { 173, 5 },
+  { 172, 1 },
+  { 172, 1 },
+  { 173, 1 },
+  { 173, 3 },
+  { 173, 6 },
+  { 173, 5 },
+  { 173, 4 },
+  { 172, 1 },
+  { 173, 3 },
+  { 173, 3 },
+  { 173, 3 },
+  { 173, 3 },
+  { 173, 3 },
+  { 173, 3 },
+  { 173, 3 },
+  { 173, 3 },
+  { 221, 1 },
+  { 221, 2 },
+  { 173, 3 },
+  { 173, 5 },
+  { 173, 2 },
+  { 173, 3 },
+  { 173, 3 },
+  { 173, 4 },
+  { 173, 2 },
+  { 173, 2 },
+  { 173, 2 },
+  { 173, 2 },
+  { 222, 1 },
+  { 222, 2 },
+  { 173, 5 },
   { 223, 1 },
   { 223, 2 },
-  { 175, 3 },
-  { 175, 5 },
-  { 175, 2 },
-  { 175, 3 },
-  { 175, 3 },
-  { 175, 4 },
-  { 175, 2 },
-  { 175, 2 },
-  { 175, 2 },
-  { 175, 2 },
-  { 224, 1 },
-  { 224, 2 },
-  { 175, 5 },
-  { 225, 1 },
-  { 225, 2 },
-  { 175, 5 },
-  { 175, 3 },
-  { 175, 5 },
-  { 175, 4 },
-  { 175, 4 },
-  { 175, 5 },
-  { 227, 5 },
-  { 227, 4 },
-  { 228, 2 },
-  { 228, 0 },
-  { 226, 1 },
+  { 173, 5 },
+  { 173, 3 },
+  { 173, 5 },
+  { 173, 4 },
+  { 173, 4 },
+  { 173, 5 },
+  { 225, 5 },
+  { 225, 4 },
+  { 226, 2 },
   { 226, 0 },
-  { 210, 1 },
-  { 210, 0 },
-  { 209, 3 },
-  { 209, 1 },
+  { 224, 1 },
+  { 224, 0 },
+  { 208, 0 },
+  { 207, 3 },
+  { 207, 1 },
   { 149, 12 },
-  { 229, 1 },
-  { 229, 0 },
-  { 179, 0 },
-  { 179, 3 },
-  { 189, 5 },
-  { 189, 3 },
-  { 230, 0 },
-  { 230, 2 },
+  { 227, 1 },
+  { 227, 0 },
+  { 177, 0 },
+  { 177, 3 },
+  { 187, 5 },
+  { 187, 3 },
+  { 228, 0 },
+  { 228, 2 },
   { 149, 4 },
   { 149, 1 },
   { 149, 2 },
@@ -130099,77 +132934,113 @@ static const struct {
   { 149, 6 },
   { 149, 5 },
   { 149, 6 },
-  { 231, 1 },
-  { 231, 1 },
-  { 231, 1 },
-  { 231, 1 },
-  { 231, 1 },
-  { 171, 2 },
-  { 171, 1 },
-  { 172, 2 },
+  { 169, 2 },
+  { 170, 2 },
   { 149, 5 },
-  { 232, 11 },
-  { 234, 1 },
-  { 234, 1 },
-  { 234, 2 },
-  { 234, 0 },
-  { 235, 1 },
-  { 235, 1 },
-  { 235, 3 },
-  { 236, 0 },
-  { 236, 3 },
-  { 237, 0 },
-  { 237, 2 },
+  { 230, 11 },
+  { 232, 1 },
+  { 232, 1 },
+  { 232, 2 },
+  { 232, 0 },
+  { 233, 1 },
+  { 233, 1 },
   { 233, 3 },
-  { 233, 2 },
-  { 239, 1 },
-  { 239, 3 },
-  { 240, 0 },
-  { 240, 3 },
-  { 240, 2 },
-  { 238, 7 },
-  { 238, 5 },
-  { 238, 5 },
-  { 238, 1 },
-  { 175, 4 },
-  { 175, 6 },
-  { 193, 1 },
-  { 193, 1 },
-  { 193, 1 },
+  { 235, 0 },
+  { 235, 2 },
+  { 231, 3 },
+  { 231, 2 },
+  { 237, 3 },
+  { 238, 3 },
+  { 238, 2 },
+  { 236, 7 },
+  { 236, 5 },
+  { 236, 5 },
+  { 236, 1 },
+  { 173, 4 },
+  { 173, 6 },
+  { 191, 1 },
+  { 191, 1 },
+  { 191, 1 },
   { 149, 4 },
   { 149, 6 },
   { 149, 3 },
-  { 242, 0 },
-  { 242, 2 },
-  { 241, 1 },
-  { 241, 0 },
+  { 240, 0 },
+  { 240, 2 },
   { 149, 1 },
   { 149, 3 },
   { 149, 1 },
   { 149, 3 },
   { 149, 6 },
-  { 149, 6 },
-  { 243, 1 },
-  { 244, 0 },
-  { 244, 1 },
+  { 149, 7 },
+  { 241, 1 },
   { 149, 1 },
   { 149, 4 },
-  { 245, 8 },
+  { 243, 8 },
+  { 245, 0 },
   { 246, 1 },
   { 246, 3 },
-  { 247, 0 },
-  { 247, 2 },
-  { 248, 1 },
-  { 248, 3 },
-  { 249, 1 },
-  { 250, 0 },
-  { 250, 4 },
-  { 250, 2 },
-  { 198, 0 },
-  { 198, 2 },
-  { 198, 3 },
-  { 251, 6 },
-  { 251, 8 },
+  { 247, 1 },
+  { 196, 0 },
+  { 196, 2 },
+  { 196, 3 },
+  { 249, 6 },
+  { 249, 8 },
+  { 144, 1 },
+  { 145, 2 },
+  { 145, 1 },
+  { 146, 1 },
+  { 146, 3 },
+  { 147, 0 },
+  { 151, 0 },
+  { 151, 1 },
+  { 151, 2 },
+  { 153, 1 },
+  { 153, 0 },
+  { 149, 2 },
+  { 160, 4 },
+  { 160, 2 },
+  { 152, 1 },
+  { 152, 1 },
+  { 152, 1 },
+  { 166, 1 },
+  { 167, 1 },
+  { 168, 1 },
+  { 168, 1 },
+  { 165, 2 },
+  { 165, 0 },
+  { 171, 2 },
+  { 161, 2 },
+  { 183, 3 },
+  { 183, 1 },
+  { 184, 0 },
+  { 188, 1 },
+  { 190, 1 },
+  { 194, 1 },
+  { 195, 1 },
+  { 209, 2 },
+  { 210, 1 },
+  { 173, 1 },
+  { 208, 1 },
+  { 229, 1 },
+  { 229, 1 },
+  { 229, 1 },
+  { 229, 1 },
+  { 229, 1 },
+  { 169, 1 },
+  { 234, 0 },
+  { 234, 3 },
+  { 237, 1 },
+  { 238, 0 },
+  { 239, 1 },
+  { 239, 0 },
+  { 242, 0 },
+  { 242, 1 },
+  { 244, 1 },
+  { 244, 3 },
+  { 245, 2 },
+  { 248, 0 },
+  { 248, 4 },
+  { 248, 2 },
 };
 
 static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -130180,24 +133051,46 @@ static void yy_accept(yyParser*);  /* Forward Declaration */
 */
 static void yy_reduce(
   yyParser *yypParser,         /* The parser */
-  int yyruleno                 /* Number of the rule by which to reduce */
+  unsigned int yyruleno        /* Number of the rule by which to reduce */
 ){
   int yygoto;                     /* The next state */
   int yyact;                      /* The next action */
-  YYMINORTYPE yygotominor;        /* The LHS of the rule reduced */
   yyStackEntry *yymsp;            /* The top of the parser's stack */
   int yysize;                     /* Amount to pop the stack */
   sqlite3ParserARG_FETCH;
   yymsp = &yypParser->yystack[yypParser->yyidx];
 #ifndef NDEBUG
-  if( yyTraceFILE && yyruleno>=0 
-        && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
+  if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
     yysize = yyRuleInfo[yyruleno].nrhs;
     fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
       yyRuleName[yyruleno], yymsp[-yysize].stateno);
   }
 #endif /* NDEBUG */
-  yygotominor = yyzerominor;
+
+  /* Check that the stack is large enough to grow by a single entry
+  ** if the RHS of the rule is empty.  This ensures that there is room
+  ** enough on the stack to push the LHS value */
+  if( yyRuleInfo[yyruleno].nrhs==0 ){
+#ifdef YYTRACKMAXSTACKDEPTH
+    if( yypParser->yyidx>yypParser->yyidxMax ){
+      yypParser->yyidxMax = yypParser->yyidx;
+    }
+#endif
+#if YYSTACKDEPTH>0 
+    if( yypParser->yyidx>=YYSTACKDEPTH-1 ){
+      yyStackOverflow(yypParser);
+      return;
+    }
+#else
+    if( yypParser->yyidx>=yypParser->yystksz-1 ){
+      yyGrowStack(yypParser);
+      if( yypParser->yyidx>=yypParser->yystksz-1 ){
+        yyStackOverflow(yypParser);
+        return;
+      }
+    }
+#endif
+  }
 
   switch( yyruleno ){
   /* Beginning here are the reduction cases.  A typical example
@@ -130209,322 +133102,286 @@ static void yy_reduce(
   **     break;
   */
 /********** Begin reduce actions **********************************************/
-      case 6: /* explain ::= EXPLAIN */
+        YYMINORTYPE yylhsminor;
+      case 0: /* explain ::= EXPLAIN */
 { pParse->explain = 1; }
         break;
-      case 7: /* explain ::= EXPLAIN QUERY PLAN */
+      case 1: /* explain ::= EXPLAIN QUERY PLAN */
 { pParse->explain = 2; }
         break;
-      case 8: /* cmdx ::= cmd */
+      case 2: /* cmdx ::= cmd */
 { sqlite3FinishCoding(pParse); }
         break;
-      case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);}
+      case 3: /* cmd ::= BEGIN transtype trans_opt */
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy392);}
         break;
-      case 13: /* transtype ::= */
-{yygotominor.yy4 = TK_DEFERRED;}
+      case 4: /* transtype ::= */
+{yymsp[1].minor.yy392 = TK_DEFERRED;}
         break;
-      case 14: /* transtype ::= DEFERRED */
-      case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
-      case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
-      case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
-      case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
-{yygotominor.yy4 = yymsp[0].major;}
+      case 5: /* transtype ::= DEFERRED */
+      case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
+      case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
+{yymsp[0].minor.yy392 = yymsp[0].major; /*A-overwrites-X*/}
         break;
-      case 17: /* cmd ::= COMMIT trans_opt */
-      case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
+      case 8: /* cmd ::= COMMIT trans_opt */
+      case 9: /* cmd ::= END trans_opt */ yytestcase(yyruleno==9);
 {sqlite3CommitTransaction(pParse);}
         break;
-      case 19: /* cmd ::= ROLLBACK trans_opt */
+      case 10: /* cmd ::= ROLLBACK trans_opt */
 {sqlite3RollbackTransaction(pParse);}
         break;
-      case 22: /* cmd ::= SAVEPOINT nm */
+      case 11: /* cmd ::= SAVEPOINT nm */
 {
   sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
 }
         break;
-      case 23: /* cmd ::= RELEASE savepoint_opt nm */
+      case 12: /* cmd ::= RELEASE savepoint_opt nm */
 {
   sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
 }
         break;
-      case 24: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+      case 13: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
 {
   sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
 }
         break;
-      case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+      case 14: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
 {
-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4);
+   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy392,0,0,yymsp[-2].minor.yy392);
 }
         break;
-      case 27: /* createkw ::= CREATE */
-{
-  disableLookaside(pParse);
-  yygotominor.yy0 = yymsp[0].minor.yy0;
-}
+      case 15: /* createkw ::= CREATE */
+{disableLookaside(pParse);}
         break;
-      case 28: /* ifnotexists ::= */
-      case 31: /* temp ::= */ yytestcase(yyruleno==31);
-      case 34: /* table_options ::= */ yytestcase(yyruleno==34);
-      case 68: /* autoinc ::= */ yytestcase(yyruleno==68);
-      case 81: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==81);
-      case 83: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==83);
-      case 85: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==85);
-      case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97);
-      case 108: /* ifexists ::= */ yytestcase(yyruleno==108);
-      case 124: /* distinct ::= */ yytestcase(yyruleno==124);
-      case 219: /* between_op ::= BETWEEN */ yytestcase(yyruleno==219);
-      case 222: /* in_op ::= IN */ yytestcase(yyruleno==222);
-      case 247: /* collate ::= */ yytestcase(yyruleno==247);
-{yygotominor.yy4 = 0;}
+      case 16: /* ifnotexists ::= */
+      case 19: /* temp ::= */ yytestcase(yyruleno==19);
+      case 22: /* table_options ::= */ yytestcase(yyruleno==22);
+      case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
+      case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
+      case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
+      case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
+      case 90: /* distinct ::= */ yytestcase(yyruleno==90);
+      case 209: /* collate ::= */ yytestcase(yyruleno==209);
+{yymsp[1].minor.yy392 = 0;}
         break;
-      case 29: /* ifnotexists ::= IF NOT EXISTS */
-      case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
-      case 69: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==69);
-      case 84: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==84);
-      case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107);
-      case 220: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==220);
-      case 223: /* in_op ::= NOT IN */ yytestcase(yyruleno==223);
-      case 248: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==248);
-{yygotominor.yy4 = 1;}
+      case 17: /* ifnotexists ::= IF NOT EXISTS */
+{yymsp[-2].minor.yy392 = 1;}
         break;
-      case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
+      case 18: /* temp ::= TEMP */
+      case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
+{yymsp[0].minor.yy392 = 1;}
+        break;
+      case 20: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
 {
-  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy4,0);
+  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy392,0);
 }
         break;
-      case 33: /* create_table_args ::= AS select */
+      case 21: /* create_table_args ::= AS select */
 {
-  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy387);
-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
+  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy159);
+  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
 }
         break;
-      case 35: /* table_options ::= WITHOUT nm */
+      case 23: /* table_options ::= WITHOUT nm */
 {
   if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
-    yygotominor.yy4 = TF_WithoutRowid | TF_NoVisibleRowid;
+    yymsp[-1].minor.yy392 = TF_WithoutRowid | TF_NoVisibleRowid;
   }else{
-    yygotominor.yy4 = 0;
+    yymsp[-1].minor.yy392 = 0;
     sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
   }
 }
         break;
-      case 38: /* column ::= columnid type carglist */
-{
-  yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
-  yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
-}
-        break;
-      case 39: /* columnid ::= nm */
-{
-  sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
-  yygotominor.yy0 = yymsp[0].minor.yy0;
-  pParse->constraintName.n = 0;
-}
-        break;
-      case 40: /* nm ::= ID|INDEXED */
-      case 41: /* nm ::= STRING */ yytestcase(yyruleno==41);
-      case 42: /* nm ::= JOIN_KW */ yytestcase(yyruleno==42);
-      case 45: /* typetoken ::= typename */ yytestcase(yyruleno==45);
-      case 48: /* typename ::= ID|STRING */ yytestcase(yyruleno==48);
-      case 130: /* as ::= AS nm */ yytestcase(yyruleno==130);
-      case 131: /* as ::= ID|STRING */ yytestcase(yyruleno==131);
-      case 142: /* dbnm ::= DOT nm */ yytestcase(yyruleno==142);
-      case 151: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==151);
-      case 257: /* nmnum ::= plus_num */ yytestcase(yyruleno==257);
-      case 258: /* nmnum ::= nm */ yytestcase(yyruleno==258);
-      case 259: /* nmnum ::= ON */ yytestcase(yyruleno==259);
-      case 260: /* nmnum ::= DELETE */ yytestcase(yyruleno==260);
-      case 261: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==261);
-      case 262: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==262);
-      case 263: /* plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==263);
-      case 264: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==264);
-      case 280: /* trnm ::= nm */ yytestcase(yyruleno==280);
-{yygotominor.yy0 = yymsp[0].minor.yy0;}
+      case 24: /* columnname ::= nm typetoken */
+{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
         break;
-      case 44: /* type ::= typetoken */
-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
+      case 25: /* typetoken ::= */
+      case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
+      case 96: /* as ::= */ yytestcase(yyruleno==96);
+{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
         break;
-      case 46: /* typetoken ::= typename LP signed RP */
+      case 26: /* typetoken ::= typename LP signed RP */
 {
-  yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
-  yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
+  yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
 }
         break;
-      case 47: /* typetoken ::= typename LP signed COMMA signed RP */
+      case 27: /* typetoken ::= typename LP signed COMMA signed RP */
 {
-  yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
-  yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
+  yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
 }
         break;
-      case 49: /* typename ::= typename ID|STRING */
-{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
+      case 28: /* typename ::= typename ID|STRING */
+{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
         break;
-      case 54: /* ccons ::= CONSTRAINT nm */
-      case 92: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92);
+      case 29: /* ccons ::= CONSTRAINT nm */
+      case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62);
 {pParse->constraintName = yymsp[0].minor.yy0;}
         break;
-      case 55: /* ccons ::= DEFAULT term */
-      case 57: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==57);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);}
+      case 30: /* ccons ::= DEFAULT term */
+      case 32: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==32);
+{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);}
         break;
-      case 56: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);}
+      case 31: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);}
         break;
-      case 58: /* ccons ::= DEFAULT MINUS term */
+      case 33: /* ccons ::= DEFAULT MINUS term */
 {
   ExprSpan v;
-  v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0);
+  v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0);
   v.zStart = yymsp[-1].minor.yy0.z;
-  v.zEnd = yymsp[0].minor.yy118.zEnd;
+  v.zEnd = yymsp[0].minor.yy342.zEnd;
   sqlite3AddDefaultValue(pParse,&v);
 }
         break;
-      case 59: /* ccons ::= DEFAULT ID|INDEXED */
+      case 34: /* ccons ::= DEFAULT ID|INDEXED */
 {
   ExprSpan v;
-  spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
+  spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0);
   sqlite3AddDefaultValue(pParse,&v);
 }
         break;
-      case 61: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);}
+      case 35: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);}
         break;
-      case 62: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);}
+      case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
         break;
-      case 63: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);}
+      case 37: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
         break;
-      case 64: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.pExpr);}
+      case 38: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);}
         break;
-      case 65: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);}
+      case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);}
         break;
-      case 66: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);}
+      case 40: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
         break;
-      case 67: /* ccons ::= COLLATE ID|STRING */
+      case 41: /* ccons ::= COLLATE ID|STRING */
 {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
         break;
-      case 70: /* refargs ::= */
-{ yygotominor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */}
+      case 44: /* refargs ::= */
+{ yymsp[1].minor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */}
+        break;
+      case 45: /* refargs ::= refargs refarg */
+{ yymsp[-1].minor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
         break;
-      case 71: /* refargs ::= refargs refarg */
-{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; }
+      case 46: /* refarg ::= MATCH nm */
+{ yymsp[-1].minor.yy207.value = 0;     yymsp[-1].minor.yy207.mask = 0x000000; }
         break;
-      case 72: /* refarg ::= MATCH nm */
-      case 73: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==73);
-{ yygotominor.yy215.value = 0;     yygotominor.yy215.mask = 0x000000; }
+      case 47: /* refarg ::= ON INSERT refact */
+{ yymsp[-2].minor.yy207.value = 0;     yymsp[-2].minor.yy207.mask = 0x000000; }
         break;
-      case 74: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy215.value = yymsp[0].minor.yy4;     yygotominor.yy215.mask = 0x0000ff; }
+      case 48: /* refarg ::= ON DELETE refact */
+{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy392;     yymsp[-2].minor.yy207.mask = 0x0000ff; }
         break;
-      case 75: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8;  yygotominor.yy215.mask = 0x00ff00; }
+      case 49: /* refarg ::= ON UPDATE refact */
+{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy392<<8;  yymsp[-2].minor.yy207.mask = 0x00ff00; }
         break;
-      case 76: /* refact ::= SET NULL */
-{ yygotominor.yy4 = OE_SetNull;  /* EV: R-33326-45252 */}
+      case 50: /* refact ::= SET NULL */
+{ yymsp[-1].minor.yy392 = OE_SetNull;  /* EV: R-33326-45252 */}
         break;
-      case 77: /* refact ::= SET DEFAULT */
-{ yygotominor.yy4 = OE_SetDflt;  /* EV: R-33326-45252 */}
+      case 51: /* refact ::= SET DEFAULT */
+{ yymsp[-1].minor.yy392 = OE_SetDflt;  /* EV: R-33326-45252 */}
         break;
-      case 78: /* refact ::= CASCADE */
-{ yygotominor.yy4 = OE_Cascade;  /* EV: R-33326-45252 */}
+      case 52: /* refact ::= CASCADE */
+{ yymsp[0].minor.yy392 = OE_Cascade;  /* EV: R-33326-45252 */}
         break;
-      case 79: /* refact ::= RESTRICT */
-{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */}
+      case 53: /* refact ::= RESTRICT */
+{ yymsp[0].minor.yy392 = OE_Restrict; /* EV: R-33326-45252 */}
         break;
-      case 80: /* refact ::= NO ACTION */
-{ yygotominor.yy4 = OE_None;     /* EV: R-33326-45252 */}
+      case 54: /* refact ::= NO ACTION */
+{ yymsp[-1].minor.yy392 = OE_None;     /* EV: R-33326-45252 */}
         break;
-      case 82: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
-      case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98);
-      case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100);
-      case 102: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==102);
-      case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103);
-      case 178: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==178);
-{yygotominor.yy4 = yymsp[0].minor.yy4;}
+      case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+{yymsp[-2].minor.yy392 = 0;}
         break;
-      case 86: /* conslist_opt ::= */
-{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
+      case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+      case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
+      case 142: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==142);
+{yymsp[-1].minor.yy392 = yymsp[0].minor.yy392;}
         break;
-      case 87: /* conslist_opt ::= COMMA conslist */
-{yygotominor.yy0 = yymsp[-1].minor.yy0;}
+      case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+      case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
+      case 183: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==183);
+      case 186: /* in_op ::= NOT IN */ yytestcase(yyruleno==186);
+      case 210: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==210);
+{yymsp[-1].minor.yy392 = 1;}
         break;
-      case 90: /* tconscomma ::= COMMA */
+      case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+{yymsp[-1].minor.yy392 = 0;}
+        break;
+      case 61: /* tconscomma ::= COMMA */
 {pParse->constraintName.n = 0;}
         break;
-      case 93: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);}
+      case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);}
         break;
-      case 94: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);}
+      case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);}
         break;
-      case 95: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);}
+      case 65: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);}
         break;
-      case 96: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+      case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
 {
-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4);
-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4);
+    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392);
+    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392);
 }
         break;
-      case 99: /* onconf ::= */
-      case 101: /* orconf ::= */ yytestcase(yyruleno==101);
-{yygotominor.yy4 = OE_Default;}
+      case 68: /* onconf ::= */
+      case 70: /* orconf ::= */ yytestcase(yyruleno==70);
+{yymsp[1].minor.yy392 = OE_Default;}
+        break;
+      case 69: /* onconf ::= ON CONFLICT resolvetype */
+{yymsp[-2].minor.yy392 = yymsp[0].minor.yy392;}
         break;
-      case 104: /* resolvetype ::= IGNORE */
-{yygotominor.yy4 = OE_Ignore;}
+      case 72: /* resolvetype ::= IGNORE */
+{yymsp[0].minor.yy392 = OE_Ignore;}
         break;
-      case 105: /* resolvetype ::= REPLACE */
-      case 179: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==179);
-{yygotominor.yy4 = OE_Replace;}
+      case 73: /* resolvetype ::= REPLACE */
+      case 143: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==143);
+{yymsp[0].minor.yy392 = OE_Replace;}
         break;
-      case 106: /* cmd ::= DROP TABLE ifexists fullname */
+      case 74: /* cmd ::= DROP TABLE ifexists fullname */
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
 }
         break;
-      case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+      case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
 {
-  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy387, yymsp[-7].minor.yy4, yymsp[-5].minor.yy4);
+  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[0].minor.yy159, yymsp[-7].minor.yy392, yymsp[-5].minor.yy392);
 }
         break;
-      case 110: /* cmd ::= DROP VIEW ifexists fullname */
+      case 78: /* cmd ::= DROP VIEW ifexists fullname */
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
 }
         break;
-      case 111: /* cmd ::= select */
+      case 79: /* cmd ::= select */
 {
   SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
-  sqlite3Select(pParse, yymsp[0].minor.yy387, &dest);
-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
+  sqlite3Select(pParse, yymsp[0].minor.yy159, &dest);
+  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
 }
         break;
-      case 112: /* select ::= with selectnowith */
+      case 80: /* select ::= with selectnowith */
 {
-  Select *p = yymsp[0].minor.yy387;
+  Select *p = yymsp[0].minor.yy159;
   if( p ){
-    p->pWith = yymsp[-1].minor.yy451;
+    p->pWith = yymsp[-1].minor.yy331;
     parserDoubleLinkSelect(pParse, p);
   }else{
-    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy451);
+    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy331);
   }
-  yygotominor.yy387 = p;
+  yymsp[-1].minor.yy159 = p; /*A-overwrites-W*/
 }
         break;
-      case 113: /* selectnowith ::= oneselect */
-      case 119: /* oneselect ::= values */ yytestcase(yyruleno==119);
-{yygotominor.yy387 = yymsp[0].minor.yy387;}
-        break;
-      case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */
+      case 81: /* selectnowith ::= selectnowith multiselect_op oneselect */
 {
-  Select *pRhs = yymsp[0].minor.yy387;
-  Select *pLhs = yymsp[-2].minor.yy387;
+  Select *pRhs = yymsp[0].minor.yy159;
+  Select *pLhs = yymsp[-2].minor.yy159;
   if( pRhs && pRhs->pPrior ){
     SrcList *pFrom;
     Token x;
@@ -130534,23 +133391,30 @@ static void yy_reduce(
     pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
   }
   if( pRhs ){
-    pRhs->op = (u8)yymsp[-1].minor.yy4;
+    pRhs->op = (u8)yymsp[-1].minor.yy392;
     pRhs->pPrior = pLhs;
     if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
     pRhs->selFlags &= ~SF_MultiValue;
-    if( yymsp[-1].minor.yy4!=TK_ALL ) pParse->hasCompound = 1;
+    if( yymsp[-1].minor.yy392!=TK_ALL ) pParse->hasCompound = 1;
   }else{
     sqlite3SelectDelete(pParse->db, pLhs);
   }
-  yygotominor.yy387 = pRhs;
+  yymsp[-2].minor.yy159 = pRhs;
 }
         break;
-      case 116: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy4 = TK_ALL;}
+      case 82: /* multiselect_op ::= UNION */
+      case 84: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==84);
+{yymsp[0].minor.yy392 = yymsp[0].major; /*A-overwrites-OP*/}
         break;
-      case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+      case 83: /* multiselect_op ::= UNION ALL */
+{yymsp[-1].minor.yy392 = TK_ALL;}
+        break;
+      case 85: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
 {
-  yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy4,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset);
+#if SELECTTRACE_ENABLED
+  Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/
+#endif
+  yymsp[-8].minor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
 #if SELECTTRACE_ENABLED
   /* Populate the Select.zSelName[] string that is used to help with
   ** query planner debugging, to differentiate between multiple Select
@@ -130561,470 +133425,473 @@ static void yy_reduce(
   ** comment to be the zSelName value.  Otherwise, the label is #N where
   ** is an integer that is incremented with each SELECT statement seen.
   */
-  if( yygotominor.yy387!=0 ){
-    const char *z = yymsp[-8].minor.yy0.z+6;
+  if( yymsp[-8].minor.yy159!=0 ){
+    const char *z = s.z+6;
     int i;
-    sqlite3_snprintf(sizeof(yygotominor.yy387->zSelName), yygotominor.yy387->zSelName, "#%d",
+    sqlite3_snprintf(sizeof(yymsp[-8].minor.yy159->zSelName), yymsp[-8].minor.yy159->zSelName, "#%d",
                      ++pParse->nSelect);
     while( z[0]==' ' ) z++;
     if( z[0]=='/' && z[1]=='*' ){
       z += 2;
       while( z[0]==' ' ) z++;
       for(i=0; sqlite3Isalnum(z[i]); i++){}
-      sqlite3_snprintf(sizeof(yygotominor.yy387->zSelName), yygotominor.yy387->zSelName, "%.*s", i, z);
+      sqlite3_snprintf(sizeof(yymsp[-8].minor.yy159->zSelName), yymsp[-8].minor.yy159->zSelName, "%.*s", i, z);
     }
   }
 #endif /* SELECTRACE_ENABLED */
 }
         break;
-      case 120: /* values ::= VALUES LP nexprlist RP */
+      case 86: /* values ::= VALUES LP nexprlist RP */
 {
-  yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0,0);
+  yymsp[-3].minor.yy159 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy442,0,0,0,0,0,SF_Values,0,0);
 }
         break;
-      case 121: /* values ::= values COMMA LP exprlist RP */
+      case 87: /* values ::= values COMMA LP exprlist RP */
 {
-  Select *pRight, *pLeft = yymsp[-4].minor.yy387;
-  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
+  Select *pRight, *pLeft = yymsp[-4].minor.yy159;
+  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy442,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
   if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
   if( pRight ){
     pRight->op = TK_ALL;
-    pLeft = yymsp[-4].minor.yy387;
     pRight->pPrior = pLeft;
-    yygotominor.yy387 = pRight;
+    yymsp[-4].minor.yy159 = pRight;
   }else{
-    yygotominor.yy387 = pLeft;
+    yymsp[-4].minor.yy159 = pLeft;
   }
 }
         break;
-      case 122: /* distinct ::= DISTINCT */
-{yygotominor.yy4 = SF_Distinct;}
+      case 88: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy392 = SF_Distinct;}
         break;
-      case 123: /* distinct ::= ALL */
-{yygotominor.yy4 = SF_All;}
+      case 89: /* distinct ::= ALL */
+{yymsp[0].minor.yy392 = SF_All;}
         break;
-      case 125: /* sclp ::= selcollist COMMA */
-      case 244: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==244);
-{yygotominor.yy322 = yymsp[-1].minor.yy322;}
+      case 91: /* sclp ::= */
+      case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
+      case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
+      case 199: /* exprlist ::= */ yytestcase(yyruleno==199);
+      case 205: /* eidlist_opt ::= */ yytestcase(yyruleno==205);
+{yymsp[1].minor.yy442 = 0;}
         break;
-      case 126: /* sclp ::= */
-      case 155: /* orderby_opt ::= */ yytestcase(yyruleno==155);
-      case 162: /* groupby_opt ::= */ yytestcase(yyruleno==162);
-      case 237: /* exprlist ::= */ yytestcase(yyruleno==237);
-      case 243: /* eidlist_opt ::= */ yytestcase(yyruleno==243);
-{yygotominor.yy322 = 0;}
-        break;
-      case 127: /* selcollist ::= sclp expr as */
+      case 92: /* selcollist ::= sclp expr as */
 {
-   yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr);
-   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1);
-   sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118);
+   yymsp[-2].minor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr);
+   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-2].minor.yy442, &yymsp[0].minor.yy0, 1);
+   sqlite3ExprListSetSpan(pParse,yymsp[-2].minor.yy442,&yymsp[-1].minor.yy342);
 }
         break;
-      case 128: /* selcollist ::= sclp STAR */
+      case 93: /* selcollist ::= sclp STAR */
 {
   Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p);
+  yymsp[-1].minor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p);
 }
         break;
-      case 129: /* selcollist ::= sclp nm DOT STAR */
+      case 94: /* selcollist ::= sclp nm DOT STAR */
 {
   Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &yymsp[0].minor.yy0);
   Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
   Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot);
+  yymsp[-3].minor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot);
 }
         break;
-      case 132: /* as ::= */
-{yygotominor.yy0.n = 0;}
+      case 95: /* as ::= AS nm */
+      case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
+      case 219: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==219);
+      case 220: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==220);
+{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
         break;
-      case 133: /* from ::= */
-{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));}
+      case 97: /* from ::= */
+{yymsp[1].minor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy347));}
         break;
-      case 134: /* from ::= FROM seltablist */
+      case 98: /* from ::= FROM seltablist */
 {
-  yygotominor.yy259 = yymsp[0].minor.yy259;
-  sqlite3SrcListShiftJoinType(yygotominor.yy259);
+  yymsp[-1].minor.yy347 = yymsp[0].minor.yy347;
+  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy347);
 }
         break;
-      case 135: /* stl_prefix ::= seltablist joinop */
+      case 99: /* stl_prefix ::= seltablist joinop */
 {
-   yygotominor.yy259 = yymsp[-1].minor.yy259;
-   if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy4;
+   if( ALWAYS(yymsp[-1].minor.yy347 && yymsp[-1].minor.yy347->nSrc>0) ) yymsp[-1].minor.yy347->a[yymsp[-1].minor.yy347->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy392;
 }
         break;
-      case 136: /* stl_prefix ::= */
-{yygotominor.yy259 = 0;}
+      case 100: /* stl_prefix ::= */
+{yymsp[1].minor.yy347 = 0;}
         break;
-      case 137: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+      case 101: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
 {
-  yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
-  sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0);
+  yymsp[-6].minor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
+  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy347, &yymsp[-2].minor.yy0);
 }
         break;
-      case 138: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+      case 102: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
 {
-  yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy259,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
-  sqlite3SrcListFuncArgs(pParse, yygotominor.yy259, yymsp[-4].minor.yy322);
+  yymsp[-8].minor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy347,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
+  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy347, yymsp[-4].minor.yy442);
 }
         break;
-      case 139: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+      case 103: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
 {
-    yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+    yymsp[-6].minor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
   }
         break;
-      case 140: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+      case 104: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
 {
-    if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){
-      yygotominor.yy259 = yymsp[-4].minor.yy259;
-    }else if( yymsp[-4].minor.yy259->nSrc==1 ){
-      yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
-      if( yygotominor.yy259 ){
-        struct SrcList_item *pNew = &yygotominor.yy259->a[yygotominor.yy259->nSrc-1];
-        struct SrcList_item *pOld = yymsp[-4].minor.yy259->a;
+    if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
+      yymsp[-6].minor.yy347 = yymsp[-4].minor.yy347;
+    }else if( yymsp[-4].minor.yy347->nSrc==1 ){
+      yymsp[-6].minor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
+      if( yymsp[-6].minor.yy347 ){
+        struct SrcList_item *pNew = &yymsp[-6].minor.yy347->a[yymsp[-6].minor.yy347->nSrc-1];
+        struct SrcList_item *pOld = yymsp[-4].minor.yy347->a;
         pNew->zName = pOld->zName;
         pNew->zDatabase = pOld->zDatabase;
         pNew->pSelect = pOld->pSelect;
         pOld->zName = pOld->zDatabase = 0;
         pOld->pSelect = 0;
       }
-      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy259);
+      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy347);
     }else{
       Select *pSubquery;
-      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259);
-      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,SF_NestedFrom,0,0);
-      yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
+      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,SF_NestedFrom,0,0);
+      yymsp[-6].minor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
     }
   }
         break;
-      case 141: /* dbnm ::= */
-      case 150: /* indexed_opt ::= */ yytestcase(yyruleno==150);
-{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
+      case 105: /* dbnm ::= */
+      case 114: /* indexed_opt ::= */ yytestcase(yyruleno==114);
+{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
+        break;
+      case 107: /* fullname ::= nm dbnm */
+{yymsp[-1].minor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
         break;
-      case 143: /* fullname ::= nm dbnm */
-{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+      case 108: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy392 = JT_INNER; }
         break;
-      case 144: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy4 = JT_INNER; }
+      case 109: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
         break;
-      case 145: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+      case 110: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
         break;
-      case 146: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
+      case 111: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
         break;
-      case 147: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
+      case 112: /* on_opt ::= ON expr */
+      case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129);
+      case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136);
+      case 195: /* case_else ::= ELSE expr */ yytestcase(yyruleno==195);
+{yymsp[-1].minor.yy122 = yymsp[0].minor.yy342.pExpr;}
         break;
-      case 148: /* on_opt ::= ON expr */
-      case 165: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==165);
-      case 172: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==172);
-      case 232: /* case_else ::= ELSE expr */ yytestcase(yyruleno==232);
-      case 234: /* case_operand ::= expr */ yytestcase(yyruleno==234);
-{yygotominor.yy314 = yymsp[0].minor.yy118.pExpr;}
+      case 113: /* on_opt ::= */
+      case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
+      case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
+      case 196: /* case_else ::= */ yytestcase(yyruleno==196);
+      case 198: /* case_operand ::= */ yytestcase(yyruleno==198);
+{yymsp[1].minor.yy122 = 0;}
         break;
-      case 149: /* on_opt ::= */
-      case 164: /* having_opt ::= */ yytestcase(yyruleno==164);
-      case 171: /* where_opt ::= */ yytestcase(yyruleno==171);
-      case 233: /* case_else ::= */ yytestcase(yyruleno==233);
-      case 235: /* case_operand ::= */ yytestcase(yyruleno==235);
-{yygotominor.yy314 = 0;}
+      case 115: /* indexed_opt ::= INDEXED BY nm */
+{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
         break;
-      case 152: /* indexed_opt ::= NOT INDEXED */
-{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
+      case 116: /* indexed_opt ::= NOT INDEXED */
+{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
         break;
-      case 153: /* using_opt ::= USING LP idlist RP */
-      case 181: /* idlist_opt ::= LP idlist RP */ yytestcase(yyruleno==181);
-{yygotominor.yy384 = yymsp[-1].minor.yy384;}
+      case 117: /* using_opt ::= USING LP idlist RP */
+{yymsp[-3].minor.yy180 = yymsp[-1].minor.yy180;}
         break;
-      case 154: /* using_opt ::= */
-      case 180: /* idlist_opt ::= */ yytestcase(yyruleno==180);
-{yygotominor.yy384 = 0;}
+      case 118: /* using_opt ::= */
+      case 144: /* idlist_opt ::= */ yytestcase(yyruleno==144);
+{yymsp[1].minor.yy180 = 0;}
         break;
-      case 156: /* orderby_opt ::= ORDER BY sortlist */
-      case 163: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==163);
-      case 236: /* exprlist ::= nexprlist */ yytestcase(yyruleno==236);
-{yygotominor.yy322 = yymsp[0].minor.yy322;}
+      case 120: /* orderby_opt ::= ORDER BY sortlist */
+      case 127: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==127);
+{yymsp[-2].minor.yy442 = yymsp[0].minor.yy442;}
         break;
-      case 157: /* sortlist ::= sortlist COMMA expr sortorder */
+      case 121: /* sortlist ::= sortlist COMMA expr sortorder */
 {
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy118.pExpr);
-  sqlite3ExprListSetSortOrder(yygotominor.yy322,yymsp[0].minor.yy4);
+  yymsp[-3].minor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr);
+  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy442,yymsp[0].minor.yy392);
 }
         break;
-      case 158: /* sortlist ::= expr sortorder */
+      case 122: /* sortlist ::= expr sortorder */
 {
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy118.pExpr);
-  sqlite3ExprListSetSortOrder(yygotominor.yy322,yymsp[0].minor.yy4);
+  yymsp[-1].minor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr); /*A-overwrites-Y*/
+  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy442,yymsp[0].minor.yy392);
 }
         break;
-      case 159: /* sortorder ::= ASC */
-{yygotominor.yy4 = SQLITE_SO_ASC;}
+      case 123: /* sortorder ::= ASC */
+{yymsp[0].minor.yy392 = SQLITE_SO_ASC;}
         break;
-      case 160: /* sortorder ::= DESC */
-{yygotominor.yy4 = SQLITE_SO_DESC;}
+      case 124: /* sortorder ::= DESC */
+{yymsp[0].minor.yy392 = SQLITE_SO_DESC;}
         break;
-      case 161: /* sortorder ::= */
-{yygotominor.yy4 = SQLITE_SO_UNDEFINED;}
+      case 125: /* sortorder ::= */
+{yymsp[1].minor.yy392 = SQLITE_SO_UNDEFINED;}
         break;
-      case 166: /* limit_opt ::= */
-{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;}
+      case 130: /* limit_opt ::= */
+{yymsp[1].minor.yy64.pLimit = 0; yymsp[1].minor.yy64.pOffset = 0;}
         break;
-      case 167: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.pOffset = 0;}
+      case 131: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yymsp[-1].minor.yy64.pOffset = 0;}
         break;
-      case 168: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.pExpr;}
+      case 132: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yymsp[-3].minor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;}
         break;
-      case 169: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;}
+      case 133: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yymsp[-3].minor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;}
         break;
-      case 170: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt orderby_opt limit_opt */
+      case 134: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt orderby_opt limit_opt */
 {
-  sqlite3WithPush(pParse, yymsp[-7].minor.yy451, 1);
-  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0);
+  sqlite3WithPush(pParse, yymsp[-7].minor.yy331, 1);
+  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0);
 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-  yymsp[-2].minor.yy314 = sqlite3LimitWhere(pParse, yymsp[-4].minor.yy259, yymsp[-2].minor.yy314, yymsp[-1].minor.yy322, yymsp[0].minor.yy292.pLimit, yymsp[0].minor.yy292.pOffset, "DELETE");
+  yymsp[-2].minor.yy122 = sqlite3LimitWhere(pParse, yymsp[-4].minor.yy347, yymsp[-2].minor.yy122, yymsp[-1].minor.yy442, yymsp[0].minor.yy64.pLimit, yymsp[0].minor.yy64.pOffset, "DELETE");
 #else
-  if( yymsp[-1].minor.yy322 || yymsp[0].minor.yy292.pLimit ){
-    sqlite3ErrorMsg(pParse, "%s on DELETE not supported", yymsp[-1].minor.yy322?"ORDER BY":"LIMIT");
-    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy314);
-    sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
-    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy292.pLimit);
-    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy292.pOffset);
-    yymsp[-2].minor.yy314 = 0;
+  if( yymsp[-1].minor.yy442 || yymsp[0].minor.yy64.pLimit ){
+    sqlite3ErrorMsg(pParse, "%s on DELETE not supported", yymsp[-1].minor.yy442?"ORDER BY":"LIMIT");
+    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy122);
+    sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
+    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy64.pLimit);
+    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy64.pOffset);
+    yymsp[-2].minor.yy122 = 0;
   }
 #endif
-  sqlite3DeleteFrom(pParse,yymsp[-4].minor.yy259,yymsp[-2].minor.yy314);
+  sqlite3DeleteFrom(pParse,yymsp[-4].minor.yy347,yymsp[-2].minor.yy122);
 }
         break;
-      case 173: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt orderby_opt limit_opt */
+      case 137: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt orderby_opt limit_opt */
 {
-  sqlite3WithPush(pParse, yymsp[-9].minor.yy451, 1);
-  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy259, &yymsp[-5].minor.yy0);
-  sqlite3ExprListCheckLength(pParse,yymsp[-3].minor.yy322,"set list"); 
+  sqlite3WithPush(pParse, yymsp[-9].minor.yy331, 1);
+  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy347, &yymsp[-5].minor.yy0);
+  sqlite3ExprListCheckLength(pParse,yymsp[-3].minor.yy442,"set list"); 
 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-  yymsp[-2].minor.yy314 = sqlite3LimitWhere(pParse, yymsp[-6].minor.yy259, yymsp[-2].minor.yy314, yymsp[-1].minor.yy322, yymsp[0].minor.yy292.pLimit, yymsp[0].minor.yy292.pOffset, "UPDATE");
+  yymsp[-2].minor.yy122 = sqlite3LimitWhere(pParse, yymsp[-6].minor.yy347, yymsp[-2].minor.yy122, yymsp[-1].minor.yy442, yymsp[0].minor.yy64.pLimit, yymsp[0].minor.yy64.pOffset, "UPDATE");
 #else
-  if( yymsp[-1].minor.yy322 || yymsp[0].minor.yy292.pLimit ){
-    sqlite3ErrorMsg(pParse, "%s on UPDATE not supported", yymsp[-1].minor.yy322?"ORDER BY":"LIMIT");
-    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy314);
-    sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
-    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy292.pLimit);
-    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy292.pOffset);
-    yymsp[-2].minor.yy314 = 0;
+  if( yymsp[-1].minor.yy442 || yymsp[0].minor.yy64.pLimit ){
+    sqlite3ErrorMsg(pParse, "%s on UPDATE not supported", yymsp[-1].minor.yy442?"ORDER BY":"LIMIT");
+    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy122);
+    sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
+    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy64.pLimit);
+    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy64.pOffset);
+    yymsp[-2].minor.yy122 = 0;
   }
 #endif
-  sqlite3Update(pParse,yymsp[-6].minor.yy259,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-7].minor.yy4);
+  sqlite3Update(pParse,yymsp[-6].minor.yy347,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-7].minor.yy392);
 }
         break;
-      case 174: /* setlist ::= setlist COMMA nm EQ expr */
+      case 138: /* setlist ::= setlist COMMA nm EQ expr */
 {
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr);
-  sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+  yymsp[-4].minor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr);
+  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy442, &yymsp[-2].minor.yy0, 1);
 }
         break;
-      case 175: /* setlist ::= nm EQ expr */
+      case 139: /* setlist ::= nm EQ expr */
 {
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr);
-  sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+  yylhsminor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr);
+  sqlite3ExprListSetName(pParse, yylhsminor.yy442, &yymsp[-2].minor.yy0, 1);
 }
+  yymsp[-2].minor.yy442 = yylhsminor.yy442;
         break;
-      case 176: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
+      case 140: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
 {
-  sqlite3WithPush(pParse, yymsp[-5].minor.yy451, 1);
-  sqlite3Insert(pParse, yymsp[-2].minor.yy259, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy4);
+  sqlite3WithPush(pParse, yymsp[-5].minor.yy331, 1);
+  sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy392);
 }
         break;
-      case 177: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
+      case 141: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
 {
-  sqlite3WithPush(pParse, yymsp[-6].minor.yy451, 1);
-  sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy4);
+  sqlite3WithPush(pParse, yymsp[-6].minor.yy331, 1);
+  sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy392);
 }
         break;
-      case 182: /* idlist ::= idlist COMMA nm */
-{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);}
+      case 145: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy180 = yymsp[-1].minor.yy180;}
         break;
-      case 183: /* idlist ::= nm */
-{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
+      case 146: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
         break;
-      case 184: /* expr ::= term */
-{yygotominor.yy118 = yymsp[0].minor.yy118;}
+      case 147: /* idlist ::= nm */
+{yymsp[0].minor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
         break;
-      case 185: /* expr ::= LP expr RP */
-{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
+      case 148: /* expr ::= LP expr RP */
+{spanSet(&yymsp[-2].minor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/  yymsp[-2].minor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr;}
         break;
-      case 186: /* term ::= NULL */
-      case 191: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==191);
-      case 192: /* term ::= STRING */ yytestcase(yyruleno==192);
-{spanExpr(&yygotominor.yy118, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
+      case 149: /* term ::= NULL */
+      case 154: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==154);
+      case 155: /* term ::= STRING */ yytestcase(yyruleno==155);
+{spanExpr(&yymsp[0].minor.yy342,pParse,yymsp[0].major,yymsp[0].minor.yy0);/*A-overwrites-X*/}
         break;
-      case 187: /* expr ::= ID|INDEXED */
-      case 188: /* expr ::= JOIN_KW */ yytestcase(yyruleno==188);
-{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);}
+      case 150: /* expr ::= ID|INDEXED */
+      case 151: /* expr ::= JOIN_KW */ yytestcase(yyruleno==151);
+{spanExpr(&yymsp[0].minor.yy342,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
         break;
-      case 189: /* expr ::= nm DOT nm */
+      case 152: /* expr ::= nm DOT nm */
 {
   Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
   Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
-  yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
-  spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+  spanSet(&yymsp[-2].minor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
+  yymsp[-2].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
 }
         break;
-      case 190: /* expr ::= nm DOT nm DOT nm */
+      case 153: /* expr ::= nm DOT nm DOT nm */
 {
   Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
   Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
   Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
   Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
-  yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
-  spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+  spanSet(&yymsp[-4].minor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
+  yymsp[-4].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
 }
         break;
-      case 193: /* expr ::= VARIABLE */
+      case 156: /* expr ::= VARIABLE */
 {
-  if( yymsp[0].minor.yy0.n>=2 && yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1]) ){
+  if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
+    spanExpr(&yymsp[0].minor.yy342, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy342.pExpr);
+  }else{
     /* When doing a nested parse, one can include terms in an expression
     ** that look like this:   #1 #2 ...  These terms refer to registers
     ** in the virtual machine.  #N is the N-th register. */
+    Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
+    assert( t.n>=2 );
+    spanSet(&yymsp[0].minor.yy342, &t, &t);
     if( pParse->nested==0 ){
-      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
-      yygotominor.yy118.pExpr = 0;
+      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
+      yymsp[0].minor.yy342.pExpr = 0;
     }else{
-      yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
-      if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable);
+      yymsp[0].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
+      if( yymsp[0].minor.yy342.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy342.pExpr->iTable);
     }
-  }else{
-    spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
-    sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr);
   }
-  spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
 }
         break;
-      case 194: /* expr ::= expr COLLATE ID|STRING */
+      case 157: /* expr ::= expr COLLATE ID|STRING */
 {
-  yygotominor.yy118.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0, 1);
-  yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
-  yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+  yymsp[-2].minor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0, 1);
+  yymsp[-2].minor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
 }
         break;
-      case 195: /* expr ::= CAST LP expr AS typetoken RP */
+      case 158: /* expr ::= CAST LP expr AS typetoken RP */
 {
-  yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0);
-  spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+  spanSet(&yymsp[-5].minor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
+  yymsp[-5].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0);
 }
         break;
-      case 196: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+      case 159: /* expr ::= ID|INDEXED LP distinct exprlist RP */
 {
-  if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+  if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
     sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
   }
-  yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
-  spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
-  if( yymsp[-2].minor.yy4==SF_Distinct && yygotominor.yy118.pExpr ){
-    yygotominor.yy118.pExpr->flags |= EP_Distinct;
+  yylhsminor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
+  spanSet(&yylhsminor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+  if( yymsp[-2].minor.yy392==SF_Distinct && yylhsminor.yy342.pExpr ){
+    yylhsminor.yy342.pExpr->flags |= EP_Distinct;
   }
 }
+  yymsp[-4].minor.yy342 = yylhsminor.yy342;
         break;
-      case 197: /* expr ::= ID|INDEXED LP STAR RP */
+      case 160: /* expr ::= ID|INDEXED LP STAR RP */
 {
-  yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
-  spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+  yylhsminor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+  spanSet(&yylhsminor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
 }
+  yymsp[-3].minor.yy342 = yylhsminor.yy342;
         break;
-      case 198: /* term ::= CTIME_KW */
+      case 161: /* term ::= CTIME_KW */
 {
-  yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
-  spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+  yylhsminor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
+  spanSet(&yylhsminor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
 }
+  yymsp[0].minor.yy342 = yylhsminor.yy342;
         break;
-      case 199: /* expr ::= expr AND expr */
-      case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
-      case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
-      case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
-      case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
-      case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
-      case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
-      case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
-{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);}
+      case 162: /* expr ::= expr AND expr */
+      case 163: /* expr ::= expr OR expr */ yytestcase(yyruleno==163);
+      case 164: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==164);
+      case 165: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==165);
+      case 166: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==166);
+      case 167: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==167);
+      case 168: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==168);
+      case 169: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==169);
+{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);}
         break;
-      case 207: /* likeop ::= LIKE_KW|MATCH */
-{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 0;}
+      case 170: /* likeop ::= LIKE_KW|MATCH */
+{yymsp[0].minor.yy318.eOperator = yymsp[0].minor.yy0; yymsp[0].minor.yy318.bNot = 0;/*A-overwrites-X*/}
         break;
-      case 208: /* likeop ::= NOT LIKE_KW|MATCH */
-{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 1;}
+      case 171: /* likeop ::= NOT LIKE_KW|MATCH */
+{yymsp[-1].minor.yy318.eOperator = yymsp[0].minor.yy0; yymsp[-1].minor.yy318.bNot = 1;}
         break;
-      case 209: /* expr ::= expr likeop expr */
+      case 172: /* expr ::= expr likeop expr */
 {
   ExprList *pList;
-  pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr);
-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr);
-  yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator);
-  exprNot(pParse, yymsp[-1].minor.yy342.bNot, &yygotominor.yy118.pExpr);
-  yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
-  yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
-  if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
+  pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr);
+  yymsp[-2].minor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator);
+  exprNot(pParse, yymsp[-1].minor.yy318.bNot, &yymsp[-2].minor.yy342);
+  yymsp[-2].minor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
+  if( yymsp[-2].minor.yy342.pExpr ) yymsp[-2].minor.yy342.pExpr->flags |= EP_InfixFunc;
 }
         break;
-      case 210: /* expr ::= expr likeop expr ESCAPE expr */
+      case 173: /* expr ::= expr likeop expr ESCAPE expr */
 {
   ExprList *pList;
-  pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr);
-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
-  yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator);
-  exprNot(pParse, yymsp[-3].minor.yy342.bNot, &yygotominor.yy118.pExpr);
-  yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
-  yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
-  if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
+  pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
+  yymsp[-4].minor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator);
+  exprNot(pParse, yymsp[-3].minor.yy318.bNot, &yymsp[-4].minor.yy342);
+  yymsp[-4].minor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
+  if( yymsp[-4].minor.yy342.pExpr ) yymsp[-4].minor.yy342.pExpr->flags |= EP_InfixFunc;
 }
         break;
-      case 211: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&yymsp[0].minor.yy0);}
+      case 174: /* expr ::= expr ISNULL|NOTNULL */
+{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);}
         break;
-      case 212: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);}
+      case 175: /* expr ::= expr NOT NULL */
+{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);}
         break;
-      case 213: /* expr ::= expr IS expr */
+      case 176: /* expr ::= expr IS expr */
 {
-  spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);
-  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL);
+  spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);
+  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yymsp[-2].minor.yy342.pExpr, TK_ISNULL);
 }
         break;
-      case 214: /* expr ::= expr IS NOT expr */
+      case 177: /* expr ::= expr IS NOT expr */
 {
-  spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118);
-  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_NOTNULL);
+  spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342);
+  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yymsp[-3].minor.yy342.pExpr, TK_NOTNULL);
 }
         break;
-      case 215: /* expr ::= NOT expr */
-      case 216: /* expr ::= BITNOT expr */ yytestcase(yyruleno==216);
-{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+      case 178: /* expr ::= NOT expr */
+      case 179: /* expr ::= BITNOT expr */ yytestcase(yyruleno==179);
+{spanUnaryPrefix(&yymsp[-1].minor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+        break;
+      case 180: /* expr ::= MINUS expr */
+{spanUnaryPrefix(&yymsp[-1].minor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
         break;
-      case 217: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+      case 181: /* expr ::= PLUS expr */
+{spanUnaryPrefix(&yymsp[-1].minor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
         break;
-      case 218: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+      case 182: /* between_op ::= BETWEEN */
+      case 185: /* in_op ::= IN */ yytestcase(yyruleno==185);
+{yymsp[0].minor.yy392 = 0;}
         break;
-      case 221: /* expr ::= expr between_op expr AND expr */
+      case 184: /* expr ::= expr between_op expr AND expr */
 {
-  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
-  yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0);
-  if( yygotominor.yy118.pExpr ){
-    yygotominor.yy118.pExpr->x.pList = pList;
+  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
+  yymsp[-4].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0);
+  if( yymsp[-4].minor.yy342.pExpr ){
+    yymsp[-4].minor.yy342.pExpr->x.pList = pList;
   }else{
     sqlite3ExprListDelete(pParse->db, pList);
   } 
-  exprNot(pParse, yymsp[-3].minor.yy4, &yygotominor.yy118.pExpr);
-  yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
-  yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+  exprNot(pParse, yymsp[-3].minor.yy392, &yymsp[-4].minor.yy342);
+  yymsp[-4].minor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
 }
         break;
-      case 224: /* expr ::= expr in_op LP exprlist RP */
+      case 187: /* expr ::= expr in_op LP exprlist RP */
 {
-    if( yymsp[-1].minor.yy322==0 ){
+    if( yymsp[-1].minor.yy442==0 ){
       /* Expressions of the form
       **
       **      expr1 IN ()
@@ -131033,9 +133900,9 @@ static void yy_reduce(
       ** simplify to constants 0 (false) and 1 (true), respectively,
       ** regardless of the value of expr1.
       */
-      yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]);
-      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr);
-    }else if( yymsp[-1].minor.yy322->nExpr==1 ){
+      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy342.pExpr);
+      yymsp[-4].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy392]);
+    }else if( yymsp[-1].minor.yy442->nExpr==1 ){
       /* Expressions of the form:
       **
       **      expr1 IN (?1)
@@ -131052,423 +133919,413 @@ static void yy_reduce(
       ** affinity or the collating sequence to use for comparison.  Otherwise,
       ** the semantics would be subtly different from IN or NOT IN.
       */
-      Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
-      yymsp[-1].minor.yy322->a[0].pExpr = 0;
-      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
+      Expr *pRHS = yymsp[-1].minor.yy442->a[0].pExpr;
+      yymsp[-1].minor.yy442->a[0].pExpr = 0;
+      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
       /* pRHS cannot be NULL because a malloc error would have been detected
       ** before now and control would have never reached this point */
       if( ALWAYS(pRHS) ){
         pRHS->flags &= ~EP_Collate;
         pRHS->flags |= EP_Generic;
       }
-      yygotominor.yy118.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy4 ? TK_NE : TK_EQ, yymsp[-4].minor.yy118.pExpr, pRHS, 0);
+      yymsp[-4].minor.yy342.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy392 ? TK_NE : TK_EQ, yymsp[-4].minor.yy342.pExpr, pRHS, 0);
     }else{
-      yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
-      if( yygotominor.yy118.pExpr ){
-        yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322;
-        sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
+      yymsp[-4].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
+      if( yymsp[-4].minor.yy342.pExpr ){
+        yymsp[-4].minor.yy342.pExpr->x.pList = yymsp[-1].minor.yy442;
+        sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy342.pExpr);
       }else{
-        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
+        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
       }
-      exprNot(pParse, yymsp[-3].minor.yy4, &yygotominor.yy118.pExpr);
+      exprNot(pParse, yymsp[-3].minor.yy392, &yymsp[-4].minor.yy342);
     }
-    yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
-    yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+    yymsp[-4].minor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
   }
         break;
-      case 225: /* expr ::= LP select RP */
+      case 188: /* expr ::= LP select RP */
 {
-    yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
-    if( yygotominor.yy118.pExpr ){
-      yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
-      ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
-    }else{
-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
-    }
-    yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z;
-    yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+    spanSet(&yymsp[-2].minor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
+    yymsp[-2].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy342.pExpr, yymsp[-1].minor.yy159);
   }
         break;
-      case 226: /* expr ::= expr in_op LP select RP */
+      case 189: /* expr ::= expr in_op LP select RP */
 {
-    yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
-    if( yygotominor.yy118.pExpr ){
-      yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
-      ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
-    }else{
-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
-    }
-    exprNot(pParse, yymsp[-3].minor.yy4, &yygotominor.yy118.pExpr);
-    yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
-    yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+    yymsp[-4].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
+    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy342.pExpr, yymsp[-1].minor.yy159);
+    exprNot(pParse, yymsp[-3].minor.yy392, &yymsp[-4].minor.yy342);
+    yymsp[-4].minor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
   }
         break;
-      case 227: /* expr ::= expr in_op nm dbnm */
+      case 190: /* expr ::= expr in_op nm dbnm */
 {
     SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
-    yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0);
-    if( yygotominor.yy118.pExpr ){
-      yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
-      ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
-    }else{
-      sqlite3SrcListDelete(pParse->db, pSrc);
-    }
-    exprNot(pParse, yymsp[-2].minor.yy4, &yygotominor.yy118.pExpr);
-    yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart;
-    yygotominor.yy118.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
+    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+    yymsp[-3].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0);
+    sqlite3PExprAddSelect(pParse, yymsp[-3].minor.yy342.pExpr, pSelect);
+    exprNot(pParse, yymsp[-2].minor.yy392, &yymsp[-3].minor.yy342);
+    yymsp[-3].minor.yy342.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
   }
         break;
-      case 228: /* expr ::= EXISTS LP select RP */
+      case 191: /* expr ::= EXISTS LP select RP */
 {
-    Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
-    if( p ){
-      p->x.pSelect = yymsp[-1].minor.yy387;
-      ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeightAndFlags(pParse, p);
-    }else{
-      sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
-    }
-    yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
-    yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+    Expr *p;
+    spanSet(&yymsp[-3].minor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
+    p = yymsp[-3].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy159);
   }
         break;
-      case 229: /* expr ::= CASE case_operand case_exprlist case_else END */
+      case 192: /* expr ::= CASE case_operand case_exprlist case_else END */
 {
-  yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, 0, 0);
-  if( yygotominor.yy118.pExpr ){
-    yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy314 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy314) : yymsp[-2].minor.yy322;
-    sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
+  spanSet(&yymsp[-4].minor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);  /*A-overwrites-C*/
+  yymsp[-4].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, 0, 0);
+  if( yymsp[-4].minor.yy342.pExpr ){
+    yymsp[-4].minor.yy342.pExpr->x.pList = yymsp[-1].minor.yy122 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[-1].minor.yy122) : yymsp[-2].minor.yy442;
+    sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy342.pExpr);
   }else{
-    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
-    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy314);
+    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
+    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy122);
   }
-  yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z;
-  yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
 }
         break;
-      case 230: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+      case 193: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
 {
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr);
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
+  yymsp[-4].minor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr);
+  yymsp[-4].minor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr);
 }
         break;
-      case 231: /* case_exprlist ::= WHEN expr THEN expr */
+      case 194: /* case_exprlist ::= WHEN expr THEN expr */
 {
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
-  yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
+  yymsp[-3].minor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
+  yymsp[-3].minor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, yymsp[0].minor.yy342.pExpr);
 }
         break;
-      case 238: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);}
+      case 197: /* case_operand ::= expr */
+{yymsp[0].minor.yy122 = yymsp[0].minor.yy342.pExpr; /*A-overwrites-X*/}
+        break;
+      case 200: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
         break;
-      case 239: /* nexprlist ::= expr */
-{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);}
+      case 201: /* nexprlist ::= expr */
+{yymsp[0].minor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr); /*A-overwrites-Y*/}
         break;
-      case 240: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+      case 202: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
 {
   sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, 
-                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy4,
-                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy314, SQLITE_SO_ASC, yymsp[-8].minor.yy4);
+                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy442, yymsp[-10].minor.yy392,
+                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy122, SQLITE_SO_ASC, yymsp[-8].minor.yy392);
 }
         break;
-      case 241: /* uniqueflag ::= UNIQUE */
-      case 292: /* raisetype ::= ABORT */ yytestcase(yyruleno==292);
-{yygotominor.yy4 = OE_Abort;}
+      case 203: /* uniqueflag ::= UNIQUE */
+      case 244: /* raisetype ::= ABORT */ yytestcase(yyruleno==244);
+{yymsp[0].minor.yy392 = OE_Abort;}
+        break;
+      case 204: /* uniqueflag ::= */
+{yymsp[1].minor.yy392 = OE_None;}
         break;
-      case 242: /* uniqueflag ::= */
-{yygotominor.yy4 = OE_None;}
+      case 206: /* eidlist_opt ::= LP eidlist RP */
+{yymsp[-2].minor.yy442 = yymsp[-1].minor.yy442;}
         break;
-      case 245: /* eidlist ::= eidlist COMMA nm collate sortorder */
+      case 207: /* eidlist ::= eidlist COMMA nm collate sortorder */
 {
-  yygotominor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4);
+  yymsp[-4].minor.yy442 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy442, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy392, yymsp[0].minor.yy392);
 }
         break;
-      case 246: /* eidlist ::= nm collate sortorder */
+      case 208: /* eidlist ::= nm collate sortorder */
 {
-  yygotominor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4);
+  yymsp[-2].minor.yy442 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy392, yymsp[0].minor.yy392); /*A-overwrites-Y*/
 }
         break;
-      case 249: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);}
+      case 211: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);}
         break;
-      case 250: /* cmd ::= VACUUM */
-      case 251: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==251);
+      case 212: /* cmd ::= VACUUM */
+      case 213: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==213);
 {sqlite3Vacuum(pParse);}
         break;
-      case 252: /* cmd ::= PRAGMA nm dbnm */
+      case 214: /* cmd ::= PRAGMA nm dbnm */
 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
         break;
-      case 253: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+      case 215: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
         break;
-      case 254: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+      case 216: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
         break;
-      case 255: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+      case 217: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
         break;
-      case 256: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+      case 218: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
         break;
-      case 265: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+      case 221: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
 {
   Token all;
   all.z = yymsp[-3].minor.yy0.z;
   all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
-  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all);
+  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy327, &all);
 }
         break;
-      case 266: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+      case 222: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
 {
-  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4);
-  yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
+  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392);
+  yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
 }
         break;
-      case 267: /* trigger_time ::= BEFORE */
-      case 270: /* trigger_time ::= */ yytestcase(yyruleno==270);
-{ yygotominor.yy4 = TK_BEFORE; }
+      case 223: /* trigger_time ::= BEFORE */
+{ yymsp[0].minor.yy392 = TK_BEFORE; }
         break;
-      case 268: /* trigger_time ::= AFTER */
-{ yygotominor.yy4 = TK_AFTER;  }
+      case 224: /* trigger_time ::= AFTER */
+{ yymsp[0].minor.yy392 = TK_AFTER;  }
         break;
-      case 269: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy4 = TK_INSTEAD;}
+      case 225: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy392 = TK_INSTEAD;}
         break;
-      case 271: /* trigger_event ::= DELETE|INSERT */
-      case 272: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==272);
-{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;}
+      case 226: /* trigger_time ::= */
+{ yymsp[1].minor.yy392 = TK_BEFORE; }
         break;
-      case 273: /* trigger_event ::= UPDATE OF idlist */
-{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;}
+      case 227: /* trigger_event ::= DELETE|INSERT */
+      case 228: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==228);
+{yymsp[0].minor.yy410.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy410.b = 0;}
         break;
-      case 276: /* when_clause ::= */
-      case 297: /* key_opt ::= */ yytestcase(yyruleno==297);
-{ yygotominor.yy314 = 0; }
+      case 229: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy410.a = TK_UPDATE; yymsp[-2].minor.yy410.b = yymsp[0].minor.yy180;}
         break;
-      case 277: /* when_clause ::= WHEN expr */
-      case 298: /* key_opt ::= KEY expr */ yytestcase(yyruleno==298);
-{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; }
+      case 230: /* when_clause ::= */
+      case 249: /* key_opt ::= */ yytestcase(yyruleno==249);
+{ yymsp[1].minor.yy122 = 0; }
         break;
-      case 278: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+      case 231: /* when_clause ::= WHEN expr */
+      case 250: /* key_opt ::= KEY expr */ yytestcase(yyruleno==250);
+{ yymsp[-1].minor.yy122 = yymsp[0].minor.yy342.pExpr; }
+        break;
+      case 232: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
 {
-  assert( yymsp[-2].minor.yy203!=0 );
-  yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203;
-  yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203;
-  yygotominor.yy203 = yymsp[-2].minor.yy203;
+  assert( yymsp[-2].minor.yy327!=0 );
+  yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
+  yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327;
 }
         break;
-      case 279: /* trigger_cmd_list ::= trigger_cmd SEMI */
+      case 233: /* trigger_cmd_list ::= trigger_cmd SEMI */
 { 
-  assert( yymsp[-1].minor.yy203!=0 );
-  yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203;
-  yygotominor.yy203 = yymsp[-1].minor.yy203;
+  assert( yymsp[-1].minor.yy327!=0 );
+  yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327;
 }
         break;
-      case 281: /* trnm ::= nm DOT nm */
+      case 234: /* trnm ::= nm DOT nm */
 {
-  yygotominor.yy0 = yymsp[0].minor.yy0;
+  yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
   sqlite3ErrorMsg(pParse, 
         "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
         "statements within triggers");
 }
         break;
-      case 283: /* tridxby ::= INDEXED BY nm */
+      case 235: /* tridxby ::= INDEXED BY nm */
 {
   sqlite3ErrorMsg(pParse,
         "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
         "within triggers");
 }
         break;
-      case 284: /* tridxby ::= NOT INDEXED */
+      case 236: /* tridxby ::= NOT INDEXED */
 {
   sqlite3ErrorMsg(pParse,
         "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
         "within triggers");
 }
         break;
-      case 285: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
-{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy4); }
+      case 237: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+{yymsp[-6].minor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy392);}
         break;
-      case 286: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
-{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, yymsp[0].minor.yy387, yymsp[-4].minor.yy4);}
+      case 238: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
+{yymsp[-4].minor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy159, yymsp[-4].minor.yy392);/*A-overwrites-R*/}
         break;
-      case 287: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);}
+      case 239: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+{yymsp[-4].minor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);}
         break;
-      case 288: /* trigger_cmd ::= select */
-{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); }
+      case 240: /* trigger_cmd ::= select */
+{yymsp[0].minor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); /*A-overwrites-X*/}
         break;
-      case 289: /* expr ::= RAISE LP IGNORE RP */
+      case 241: /* expr ::= RAISE LP IGNORE RP */
 {
-  yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); 
-  if( yygotominor.yy118.pExpr ){
-    yygotominor.yy118.pExpr->affinity = OE_Ignore;
+  spanSet(&yymsp[-3].minor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);  /*A-overwrites-X*/
+  yymsp[-3].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); 
+  if( yymsp[-3].minor.yy342.pExpr ){
+    yymsp[-3].minor.yy342.pExpr->affinity = OE_Ignore;
   }
-  yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
-  yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
 }
         break;
-      case 290: /* expr ::= RAISE LP raisetype COMMA nm RP */
+      case 242: /* expr ::= RAISE LP raisetype COMMA nm RP */
 {
-  yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); 
-  if( yygotominor.yy118.pExpr ) {
-    yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4;
+  spanSet(&yymsp[-5].minor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);  /*A-overwrites-X*/
+  yymsp[-5].minor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); 
+  if( yymsp[-5].minor.yy342.pExpr ) {
+    yymsp[-5].minor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392;
   }
-  yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z;
-  yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
 }
         break;
-      case 291: /* raisetype ::= ROLLBACK */
-{yygotominor.yy4 = OE_Rollback;}
+      case 243: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy392 = OE_Rollback;}
         break;
-      case 293: /* raisetype ::= FAIL */
-{yygotominor.yy4 = OE_Fail;}
+      case 245: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy392 = OE_Fail;}
         break;
-      case 294: /* cmd ::= DROP TRIGGER ifexists fullname */
+      case 246: /* cmd ::= DROP TRIGGER ifexists fullname */
 {
-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4);
+  sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
 }
         break;
-      case 295: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+      case 247: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
 {
-  sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314);
+  sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122);
 }
         break;
-      case 296: /* cmd ::= DETACH database_kw_opt expr */
+      case 248: /* cmd ::= DETACH database_kw_opt expr */
 {
-  sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr);
+  sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr);
 }
         break;
-      case 301: /* cmd ::= REINDEX */
+      case 251: /* cmd ::= REINDEX */
 {sqlite3Reindex(pParse, 0, 0);}
         break;
-      case 302: /* cmd ::= REINDEX nm dbnm */
+      case 252: /* cmd ::= REINDEX nm dbnm */
 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 303: /* cmd ::= ANALYZE */
+      case 253: /* cmd ::= ANALYZE */
 {sqlite3Analyze(pParse, 0, 0);}
         break;
-      case 304: /* cmd ::= ANALYZE nm dbnm */
+      case 254: /* cmd ::= ANALYZE nm dbnm */
 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 305: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+      case 255: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
 {
-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0);
+  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
 }
         break;
-      case 306: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+      case 256: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
 {
-  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
+  yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
+  sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
 }
         break;
-      case 307: /* add_column_fullname ::= fullname */
+      case 257: /* add_column_fullname ::= fullname */
 {
   disableLookaside(pParse);
-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259);
+  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
 }
         break;
-      case 310: /* cmd ::= create_vtab */
+      case 258: /* cmd ::= create_vtab */
 {sqlite3VtabFinishParse(pParse,0);}
         break;
-      case 311: /* cmd ::= create_vtab LP vtabarglist RP */
+      case 259: /* cmd ::= create_vtab LP vtabarglist RP */
 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 312: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+      case 260: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
 {
-    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy4);
+    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy392);
 }
         break;
-      case 315: /* vtabarg ::= */
+      case 261: /* vtabarg ::= */
 {sqlite3VtabArgInit(pParse);}
         break;
-      case 317: /* vtabargtoken ::= ANY */
-      case 318: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==318);
-      case 319: /* lp ::= LP */ yytestcase(yyruleno==319);
+      case 262: /* vtabargtoken ::= ANY */
+      case 263: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==263);
+      case 264: /* lp ::= LP */ yytestcase(yyruleno==264);
 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 323: /* with ::= */
-{yygotominor.yy451 = 0;}
+      case 265: /* with ::= */
+{yymsp[1].minor.yy331 = 0;}
+        break;
+      case 266: /* with ::= WITH wqlist */
+{ yymsp[-1].minor.yy331 = yymsp[0].minor.yy331; }
         break;
-      case 324: /* with ::= WITH wqlist */
-      case 325: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==325);
-{ yygotominor.yy451 = yymsp[0].minor.yy451; }
+      case 267: /* with ::= WITH RECURSIVE wqlist */
+{ yymsp[-2].minor.yy331 = yymsp[0].minor.yy331; }
         break;
-      case 326: /* wqlist ::= nm eidlist_opt AS LP select RP */
+      case 268: /* wqlist ::= nm eidlist_opt AS LP select RP */
 {
-  yygotominor.yy451 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387);
+  yymsp[-5].minor.yy331 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy442, yymsp[-1].minor.yy159); /*A-overwrites-X*/
 }
         break;
-      case 327: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+      case 269: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
 {
-  yygotominor.yy451 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy451, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387);
+  yymsp[-7].minor.yy331 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy331, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy442, yymsp[-1].minor.yy159);
 }
         break;
       default:
-      /* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
-      /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
-      /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
-      /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
-      /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
-      /* (5) explain ::= */ yytestcase(yyruleno==5);
-      /* (10) trans_opt ::= */ yytestcase(yyruleno==10);
-      /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
-      /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
-      /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
-      /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
-      /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
-      /* (36) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==36);
-      /* (37) columnlist ::= column */ yytestcase(yyruleno==37);
-      /* (43) type ::= */ yytestcase(yyruleno==43);
-      /* (50) signed ::= plus_num */ yytestcase(yyruleno==50);
-      /* (51) signed ::= minus_num */ yytestcase(yyruleno==51);
-      /* (52) carglist ::= carglist ccons */ yytestcase(yyruleno==52);
-      /* (53) carglist ::= */ yytestcase(yyruleno==53);
-      /* (60) ccons ::= NULL onconf */ yytestcase(yyruleno==60);
-      /* (88) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==88);
-      /* (89) conslist ::= tcons */ yytestcase(yyruleno==89);
-      /* (91) tconscomma ::= */ yytestcase(yyruleno==91);
-      /* (274) foreach_clause ::= */ yytestcase(yyruleno==274);
-      /* (275) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==275);
-      /* (282) tridxby ::= */ yytestcase(yyruleno==282);
-      /* (299) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==299);
-      /* (300) database_kw_opt ::= */ yytestcase(yyruleno==300);
-      /* (308) kwcolumn_opt ::= */ yytestcase(yyruleno==308);
-      /* (309) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==309);
-      /* (313) vtabarglist ::= vtabarg */ yytestcase(yyruleno==313);
-      /* (314) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==314);
-      /* (316) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==316);
-      /* (320) anylist ::= */ yytestcase(yyruleno==320);
-      /* (321) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==321);
-      /* (322) anylist ::= anylist ANY */ yytestcase(yyruleno==322);
+      /* (270) input ::= cmdlist */ yytestcase(yyruleno==270);
+      /* (271) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==271);
+      /* (272) cmdlist ::= ecmd */ yytestcase(yyruleno==272);
+      /* (273) ecmd ::= SEMI */ yytestcase(yyruleno==273);
+      /* (274) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==274);
+      /* (275) explain ::= */ yytestcase(yyruleno==275);
+      /* (276) trans_opt ::= */ yytestcase(yyruleno==276);
+      /* (277) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==277);
+      /* (278) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==278);
+      /* (279) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==279);
+      /* (280) savepoint_opt ::= */ yytestcase(yyruleno==280);
+      /* (281) cmd ::= create_table create_table_args */ yytestcase(yyruleno==281);
+      /* (282) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==282);
+      /* (283) columnlist ::= columnname carglist */ yytestcase(yyruleno==283);
+      /* (284) nm ::= ID|INDEXED */ yytestcase(yyruleno==284);
+      /* (285) nm ::= STRING */ yytestcase(yyruleno==285);
+      /* (286) nm ::= JOIN_KW */ yytestcase(yyruleno==286);
+      /* (287) typetoken ::= typename */ yytestcase(yyruleno==287);
+      /* (288) typename ::= ID|STRING */ yytestcase(yyruleno==288);
+      /* (289) signed ::= plus_num */ yytestcase(yyruleno==289);
+      /* (290) signed ::= minus_num */ yytestcase(yyruleno==290);
+      /* (291) carglist ::= carglist ccons */ yytestcase(yyruleno==291);
+      /* (292) carglist ::= */ yytestcase(yyruleno==292);
+      /* (293) ccons ::= NULL onconf */ yytestcase(yyruleno==293);
+      /* (294) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==294);
+      /* (295) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==295);
+      /* (296) conslist ::= tcons */ yytestcase(yyruleno==296);
+      /* (297) tconscomma ::= */ yytestcase(yyruleno==297);
+      /* (298) defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==298);
+      /* (299) resolvetype ::= raisetype */ yytestcase(yyruleno==299);
+      /* (300) selectnowith ::= oneselect */ yytestcase(yyruleno==300);
+      /* (301) oneselect ::= values */ yytestcase(yyruleno==301);
+      /* (302) sclp ::= selcollist COMMA */ yytestcase(yyruleno==302);
+      /* (303) as ::= ID|STRING */ yytestcase(yyruleno==303);
+      /* (304) expr ::= term */ yytestcase(yyruleno==304);
+      /* (305) exprlist ::= nexprlist */ yytestcase(yyruleno==305);
+      /* (306) nmnum ::= plus_num */ yytestcase(yyruleno==306);
+      /* (307) nmnum ::= nm */ yytestcase(yyruleno==307);
+      /* (308) nmnum ::= ON */ yytestcase(yyruleno==308);
+      /* (309) nmnum ::= DELETE */ yytestcase(yyruleno==309);
+      /* (310) nmnum ::= DEFAULT */ yytestcase(yyruleno==310);
+      /* (311) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==311);
+      /* (312) foreach_clause ::= */ yytestcase(yyruleno==312);
+      /* (313) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==313);
+      /* (314) trnm ::= nm */ yytestcase(yyruleno==314);
+      /* (315) tridxby ::= */ yytestcase(yyruleno==315);
+      /* (316) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==316);
+      /* (317) database_kw_opt ::= */ yytestcase(yyruleno==317);
+      /* (318) kwcolumn_opt ::= */ yytestcase(yyruleno==318);
+      /* (319) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==319);
+      /* (320) vtabarglist ::= vtabarg */ yytestcase(yyruleno==320);
+      /* (321) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==321);
+      /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322);
+      /* (323) anylist ::= */ yytestcase(yyruleno==323);
+      /* (324) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==324);
+      /* (325) anylist ::= anylist ANY */ yytestcase(yyruleno==325);
         break;
 /********** End reduce actions ************************************************/
   };
   assert( (size_t)yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
   yygoto = yyRuleInfo[yyruleno].lhs;
   yysize = yyRuleInfo[yyruleno].nrhs;
-  yypParser->yyidx -= yysize;
   yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
   if( yyact <= YY_MAX_SHIFTREDUCE ){
     if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
-    /* If the reduce action popped at least
-    ** one element off the stack, then we can push the new element back
-    ** onto the stack here, and skip the stack overflow test in yy_shift().
-    ** That gives a significant speed improvement. */
-    if( yysize ){
-      yypParser->yyidx++;
-      yymsp -= yysize-1;
-      yymsp->stateno = (YYACTIONTYPE)yyact;
-      yymsp->major = (YYCODETYPE)yygoto;
-      yymsp->minor = yygotominor;
-      yyTraceShift(yypParser, yyact);
-    }else{
-      yy_shift(yypParser,yyact,yygoto,&yygotominor);
-    }
+    yypParser->yyidx -= yysize - 1;
+    yymsp -= yysize-1;
+    yymsp->stateno = (YYACTIONTYPE)yyact;
+    yymsp->major = (YYCODETYPE)yygoto;
+    yyTraceShift(yypParser, yyact);
   }else{
     assert( yyact == YY_ACCEPT_ACTION );
+    yypParser->yyidx -= yysize;
     yy_accept(yypParser);
   }
 }
@@ -131501,10 +134358,10 @@ static void yy_parse_failed(
 static void yy_syntax_error(
   yyParser *yypParser,           /* The parser */
   int yymajor,                   /* The major type of the error token */
-  YYMINORTYPE yyminor            /* The minor type of the error token */
+  sqlite3ParserTOKENTYPE yyminor         /* The minor type of the error token */
 ){
   sqlite3ParserARG_FETCH;
-#define TOKEN (yyminor.yy0)
+#define TOKEN yyminor
 /************ Begin %syntax_error code ****************************************/
 
   UNUSED_PARAMETER(yymajor);  /* Silence some compiler warnings */
@@ -131560,7 +134417,7 @@ SQLITE_PRIVATE void sqlite3Parser(
   sqlite3ParserARG_PDECL               /* Optional %extra_argument parameter */
 ){
   YYMINORTYPE yyminorunion;
-  int yyact;            /* The parser action. */
+  unsigned int yyact;   /* The parser action. */
 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
   int yyendofinput;     /* True if we are at the end of input */
 #endif
@@ -131574,14 +134431,14 @@ SQLITE_PRIVATE void sqlite3Parser(
   if( yypParser->yyidx<0 ){
 #if YYSTACKDEPTH<=0
     if( yypParser->yystksz <=0 ){
-      /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
-      yyminorunion = yyzerominor;
-      yyStackOverflow(yypParser, &yyminorunion);
+      yyStackOverflow(yypParser);
       return;
     }
 #endif
     yypParser->yyidx = 0;
+#ifndef YYNOERRORRECOVERY
     yypParser->yyerrcnt = -1;
+#endif
     yypParser->yystack[0].stateno = 0;
     yypParser->yystack[0].major = 0;
 #ifndef NDEBUG
@@ -131591,7 +134448,6 @@ SQLITE_PRIVATE void sqlite3Parser(
     }
 #endif
   }
-  yyminorunion.yy0 = yyminor;
 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
   yyendofinput = (yymajor==0);
 #endif
@@ -131607,13 +134463,16 @@ SQLITE_PRIVATE void sqlite3Parser(
     yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
     if( yyact <= YY_MAX_SHIFTREDUCE ){
       if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
-      yy_shift(yypParser,yyact,yymajor,&yyminorunion);
+      yy_shift(yypParser,yyact,yymajor,yyminor);
+#ifndef YYNOERRORRECOVERY
       yypParser->yyerrcnt--;
+#endif
       yymajor = YYNOCODE;
     }else if( yyact <= YY_MAX_REDUCE ){
       yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
     }else{
       assert( yyact == YY_ERROR_ACTION );
+      yyminorunion.yy0 = yyminor;
 #ifdef YYERRORSYMBOL
       int yymx;
 #endif
@@ -131643,7 +134502,7 @@ SQLITE_PRIVATE void sqlite3Parser(
       **
       */
       if( yypParser->yyerrcnt<0 ){
-        yy_syntax_error(yypParser,yymajor,yyminorunion);
+        yy_syntax_error(yypParser,yymajor,yyminor);
       }
       yymx = yypParser->yystack[yypParser->yyidx].major;
       if( yymx==YYERRORSYMBOL || yyerrorhit ){
@@ -131653,10 +134512,10 @@ SQLITE_PRIVATE void sqlite3Parser(
              yyTracePrompt,yyTokenName[yymajor]);
         }
 #endif
-        yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
+        yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
         yymajor = YYNOCODE;
       }else{
-         while(
+        while(
           yypParser->yyidx >= 0 &&
           yymx != YYERRORSYMBOL &&
           (yyact = yy_find_reduce_action(
@@ -131670,9 +134529,7 @@ SQLITE_PRIVATE void sqlite3Parser(
           yy_parse_failed(yypParser);
           yymajor = YYNOCODE;
         }else if( yymx!=YYERRORSYMBOL ){
-          YYMINORTYPE u2;
-          u2.YYERRSYMDT = 0;
-          yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
+          yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
         }
       }
       yypParser->yyerrcnt = 3;
@@ -131685,7 +134542,7 @@ SQLITE_PRIVATE void sqlite3Parser(
       ** Applications can set this macro (for example inside %include) if
       ** they intend to abandon the parse upon the first syntax error seen.
       */
-      yy_syntax_error(yypParser,yymajor,yyminorunion);
+      yy_syntax_error(yypParser,yymajor, yyminor);
       yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
       yymajor = YYNOCODE;
       
@@ -131700,7 +134557,7 @@ SQLITE_PRIVATE void sqlite3Parser(
       ** three input tokens have been successfully shifted.
       */
       if( yypParser->yyerrcnt<=0 ){
-        yy_syntax_error(yypParser,yymajor,yyminorunion);
+        yy_syntax_error(yypParser,yymajor, yyminor);
       }
       yypParser->yyerrcnt = 3;
       yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
@@ -132302,7 +135159,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
     case CC_BANG: {
       if( z[1]!='=' ){
         *tokenType = TK_ILLEGAL;
-        return 2;
+        return 1;
       }else{
         *tokenType = TK_NE;
         return 2;
@@ -132452,8 +135309,8 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
       *tokenType = TK_ID;
       return keywordCode((char*)z, i, tokenType);
     }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
     case CC_X: {
+#ifndef SQLITE_OMIT_BLOB_LITERAL
       testcase( z[0]=='x' ); testcase( z[0]=='X' );
       if( z[1]=='\'' ){
         *tokenType = TK_BLOB;
@@ -132465,10 +135322,10 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
         if( z[i] ) i++;
         return i;
       }
+#endif
       /* If it is not a BLOB literal, then it must be an ID, since no
       ** SQL keywords start with the letter 'x'.  Fall through */
     }
-#endif
     case CC_ID: {
       i = 1;
       break;
@@ -132512,7 +135369,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
   pEngine = sqlite3ParserAlloc(sqlite3Malloc);
   if( pEngine==0 ){
     sqlite3OomFault(db);
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   assert( pParse->pNewTable==0 );
   assert( pParse->pNewTrigger==0 );
@@ -132540,18 +135397,17 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
         break;
       }
     }else{
-      if( tokenType==TK_SEMI ) pParse->zTail = &zSql[i];
       sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
       lastTokenParsed = tokenType;
       if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
     }
   }
   assert( nErr==0 );
+  pParse->zTail = &zSql[i];
   if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
     assert( zSql[i]==0 );
     if( lastTokenParsed!=TK_SEMI ){
       sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
-      pParse->zTail = &zSql[i];
     }
     if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
       sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
@@ -132566,7 +135422,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
 #endif /* YYDEBUG */
   sqlite3ParserFree(pEngine, sqlite3_free);
   if( db->mallocFailed ){
-    pParse->rc = SQLITE_NOMEM;
+    pParse->rc = SQLITE_NOMEM_BKPT;
   }
   if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
     pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
@@ -132601,7 +135457,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
     sqlite3DeleteTable(db, pParse->pNewTable);
   }
 
-  sqlite3WithDelete(db, pParse->pWithToFree);
+  if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
   sqlite3DeleteTrigger(db, pParse->pNewTrigger);
   for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
   sqlite3DbFree(db, pParse->azVar);
@@ -132904,7 +135760,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
   if( zSql8 ){
     rc = sqlite3_complete(zSql8);
   }else{
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }
   sqlite3ValueFree(pVal);
   return rc & 0xff;
@@ -133043,7 +135899,7 @@ SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
 /* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
 ** contains the text of SQLITE_VERSION macro. 
 */
-SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
+const char sqlite3_version[] = SQLITE_VERSION;
 #endif
 
 /* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
@@ -133194,7 +136050,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
       sqlite3GlobalConfig.pInitMutex =
            sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
       if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
-        rc = SQLITE_NOMEM;
+        rc = SQLITE_NOMEM_BKPT;
       }
     }
   }
@@ -133225,7 +136081,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
   */
   sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
   if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
-    FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
     sqlite3GlobalConfig.inProgress = 1;
 #ifdef SQLITE_ENABLE_SQLLOG
     {
@@ -133233,8 +136088,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
       sqlite3_init_sqllog();
     }
 #endif
-    memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
-    sqlite3RegisterGlobalFunctions();
+    memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
+    sqlite3RegisterBuiltinFunctions();
     if( sqlite3GlobalConfig.isPCacheInit==0 ){
       rc = sqlite3PcacheInitialize();
     }
@@ -133641,6 +136496,11 @@ SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
       break;
     }
 
+    case SQLITE_CONFIG_STMTJRNL_SPILL: {
+      sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int);
+      break;
+    }
+
     default: {
       rc = SQLITE_ERROR;
       break;
@@ -133804,8 +136664,10 @@ SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
         int op;      /* The opcode */
         u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
       } aFlagOp[] = {
-        { SQLITE_DBCONFIG_ENABLE_FKEY,    SQLITE_ForeignKeys    },
-        { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger  },
+        { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
+        { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
+        { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
+        { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
       };
       unsigned int i;
       rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -133965,7 +136827,7 @@ SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){
 ** with SQLITE_ANY as the encoding.
 */
 static void functionDestroy(sqlite3 *db, FuncDef *p){
-  FuncDestructor *pDestructor = p->pDestructor;
+  FuncDestructor *pDestructor = p->u.pDestructor;
   if( pDestructor ){
     pDestructor->nRef--;
     if( pDestructor->nRef==0 ){
@@ -134147,18 +137009,17 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
   */
   sqlite3ConnectionClosed(db);
 
-  for(j=0; j<ArraySize(db->aFunc.a); j++){
-    FuncDef *pNext, *pHash, *p;
-    for(p=db->aFunc.a[j]; p; p=pHash){
-      pHash = p->pHash;
-      while( p ){
-        functionDestroy(db, p);
-        pNext = p->pNext;
-        sqlite3DbFree(db, p);
-        p = pNext;
-      }
-    }
+  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
+    FuncDef *pNext, *p;
+    p = sqliteHashData(i);
+    do{
+      functionDestroy(db, p);
+      pNext = p->pNext;
+      sqlite3DbFree(db, p);
+      p = pNext;
+    }while( p );
   }
+  sqlite3HashClear(&db->aFunc);
   for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
     CollSeq *pColl = (CollSeq *)sqliteHashData(i);
     /* Invoke any destructors registered for collation sequence user data. */
@@ -134637,7 +137498,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
   ** is being overridden/deleted but there are no active VMs, allow the
   ** operation to continue but invalidate all precompiled statements.
   */
-  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
+  p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
   if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
     if( db->nVdbeActive ){
       sqlite3ErrorWithMsg(db, SQLITE_BUSY, 
@@ -134649,10 +137510,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
     }
   }
 
-  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
+  p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
   assert(p || db->mallocFailed);
   if( !p ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
 
   /* If an older version of the function with a configured destructor is
@@ -134662,7 +137523,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
   if( pDestructor ){
     pDestructor->nRef++;
   }
-  p->pDestructor = pDestructor;
+  p->u.pDestructor = pDestructor;
   p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
   testcase( p->funcFlags & SQLITE_DETERMINISTIC );
   p->xSFunc = xSFunc ? xSFunc : xStep;
@@ -134778,7 +137639,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
   const char *zName,
   int nArg
 ){
-  int nName = sqlite3Strlen30(zName);
   int rc = SQLITE_OK;
 
 #ifdef SQLITE_ENABLE_API_ARMOR
@@ -134787,7 +137647,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
   }
 #endif
   sqlite3_mutex_enter(db->mutex);
-  if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
+  if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
     rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
                            0, sqlite3InvalidFunction, 0, 0, 0);
   }
@@ -134927,6 +137787,27 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
   return pRet;
 }
 
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Register a callback to be invoked each time a row is updated,
+** inserted or deleted using this database connection.
+*/
+SQLITE_API void *SQLITE_STDCALL sqlite3_preupdate_hook(
+  sqlite3 *db,              /* Attach the hook to this database */
+  void(*xCallback)(         /* Callback function */
+    void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64),
+  void *pArg                /* First callback argument */
+){
+  void *pRet;
+  sqlite3_mutex_enter(db->mutex);
+  pRet = db->pPreUpdateArg;
+  db->xPreUpdateCallback = xCallback;
+  db->pPreUpdateArg = pArg;
+  sqlite3_mutex_leave(db->mutex);
+  return pRet;
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
 #ifndef SQLITE_OMIT_WAL
 /*
 ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
@@ -135158,14 +138039,14 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
 SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
   const char *z;
   if( !db ){
-    return sqlite3ErrStr(SQLITE_NOMEM);
+    return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
   }
   if( !sqlite3SafetyCheckSickOrOk(db) ){
     return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
   }
   sqlite3_mutex_enter(db->mutex);
   if( db->mallocFailed ){
-    z = sqlite3ErrStr(SQLITE_NOMEM);
+    z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
   }else{
     testcase( db->pErr==0 );
     z = (char*)sqlite3_value_text(db->pErr);
@@ -135233,7 +138114,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
     return SQLITE_MISUSE_BKPT;
   }
   if( !db || db->mallocFailed ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   return db->errCode & db->errMask;
 }
@@ -135242,10 +138123,13 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
     return SQLITE_MISUSE_BKPT;
   }
   if( !db || db->mallocFailed ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }
   return db->errCode;
 }
+SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3 *db){
+  return db ? db->iSysErrno : 0;
+}  
 
 /*
 ** Return a string that describes the kind of error specified in the
@@ -135322,7 +138206,7 @@ static int createCollation(
   }
 
   pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
-  if( pColl==0 ) return SQLITE_NOMEM;
+  if( pColl==0 ) return SQLITE_NOMEM_BKPT;
   pColl->xCmp = xCompare;
   pColl->pUser = pCtx;
   pColl->xDel = xDel;
@@ -135370,8 +138254,8 @@ static const int aHardLimit[] = {
 #if SQLITE_MAX_VDBE_OP<40
 # error SQLITE_MAX_VDBE_OP must be at least 40
 #endif
-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
+#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
+# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
 #endif
 #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
 # error SQLITE_MAX_ATTACHED must be between 0 and 125
@@ -135501,7 +138385,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
 
     for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
     zFile = sqlite3_malloc64(nByte);
-    if( !zFile ) return SQLITE_NOMEM;
+    if( !zFile ) return SQLITE_NOMEM_BKPT;
 
     iIn = 5;
 #ifdef SQLITE_ALLOW_URI_AUTHORITY
@@ -135605,7 +138489,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
           const char *z;
           int mode;
         } *aMode = 0;
-        char *zModeType = 0;
+        const char *zModeType = 0;
         int mask = 0;
         int limit = 0;
 
@@ -135667,7 +138551,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
 
   }else{
     zFile = sqlite3_malloc64(nUri+2);
-    if( !zFile ) return SQLITE_NOMEM;
+    if( !zFile ) return SQLITE_NOMEM_BKPT;
     memcpy(zFile, zUri, nUri);
     zFile[nUri] = '\0';
     zFile[nUri+1] = '\0';
@@ -135824,6 +138708,9 @@ static int openDatabase(
 #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
                  | SQLITE_CellSizeCk
 #endif
+#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
+                 | SQLITE_Fts3Tokenizer
+#endif
       ;
   sqlite3HashInit(&db->aCollSeq);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -135866,7 +138753,7 @@ static int openDatabase(
                         flags | SQLITE_OPEN_MAIN_DB);
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_IOERR_NOMEM ){
-      rc = SQLITE_NOMEM;
+      rc = SQLITE_NOMEM_BKPT;
     }
     sqlite3Error(db, rc);
     goto opendb_out;
@@ -135877,13 +138764,13 @@ static int openDatabase(
   sqlite3BtreeLeave(db->aDb[0].pBt);
   db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
 
-  /* The default safety_level for the main database is 'full'; for the temp
-  ** database it is 'NONE'. This matches the pager layer defaults.  
+  /* The default safety_level for the main database is FULL; for the temp
+  ** database it is OFF. This matches the pager layer defaults.  
   */
   db->aDb[0].zName = "main";
-  db->aDb[0].safety_level = 3;
+  db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
   db->aDb[1].zName = "temp";
-  db->aDb[1].safety_level = 1;
+  db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
 
   db->magic = SQLITE_MAGIC_OPEN;
   if( db->mallocFailed ){
@@ -135895,7 +138782,7 @@ static int openDatabase(
   ** is accessed.
   */
   sqlite3Error(db, SQLITE_OK);
-  sqlite3RegisterBuiltinFunctions(db);
+  sqlite3RegisterPerConnectionBuiltinFunctions(db);
 
   /* Load automatic extensions - extensions that have been registered
   ** using the sqlite3_automatic_extension() API.
@@ -136069,7 +138956,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open16(
       SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
     }
   }else{
-    rc = SQLITE_NOMEM;
+    rc = SQLITE_NOMEM_BKPT;
   }
   sqlite3ValueFree(pVal);
 
@@ -136215,7 +139102,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
 
 /*
 ** The following routines are substitutes for constants SQLITE_CORRUPT,
-** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
+** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error
 ** constants.  They serve two purposes:
 **
 **   1.  Serve as a convenient place to set a breakpoint in a debugger
@@ -136224,28 +139111,33 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
 **   2.  Invoke sqlite3_log() to provide the source code location where
 **       a low-level error is first detected.
 */
+static int reportError(int iErr, int lineno, const char *zType){
+  sqlite3_log(iErr, "%s at line %d of [%.10s]",
+              zType, lineno, 20+sqlite3_sourceid());
+  return iErr;
+}
 SQLITE_PRIVATE int sqlite3CorruptError(int lineno){
   testcase( sqlite3GlobalConfig.xLog!=0 );
-  sqlite3_log(SQLITE_CORRUPT,
-              "database corruption at line %d of [%.10s]",
-              lineno, 20+sqlite3_sourceid());
-  return SQLITE_CORRUPT;
+  return reportError(SQLITE_CORRUPT, lineno, "database corruption");
 }
 SQLITE_PRIVATE int sqlite3MisuseError(int lineno){
   testcase( sqlite3GlobalConfig.xLog!=0 );
-  sqlite3_log(SQLITE_MISUSE, 
-              "misuse at line %d of [%.10s]",
-              lineno, 20+sqlite3_sourceid());
-  return SQLITE_MISUSE;
+  return reportError(SQLITE_MISUSE, lineno, "misuse");
 }
 SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
   testcase( sqlite3GlobalConfig.xLog!=0 );
-  sqlite3_log(SQLITE_CANTOPEN, 
-              "cannot open file at line %d of [%.10s]",
-              lineno, 20+sqlite3_sourceid());
-  return SQLITE_CANTOPEN;
+  return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
 }
-
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3NomemError(int lineno){
+  testcase( sqlite3GlobalConfig.xLog!=0 );
+  return reportError(SQLITE_NOMEM, lineno, "OOM");
+}
+SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
+  testcase( sqlite3GlobalConfig.xLog!=0 );
+  return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
+}
+#endif
 
 #ifndef SQLITE_OMIT_DEPRECATED
 /*
@@ -136339,7 +139231,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
   **        explicitly declared column. Copy meta information from *pCol.
   */ 
   if( pCol ){
-    zDataType = pCol->zType;
+    zDataType = sqlite3ColumnType(pCol,0);
     zCollSeq = pCol->zColl;
     notnull = pCol->notNull!=0;
     primarykey  = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
@@ -139045,14 +141937,14 @@ static char *fts3QuoteId(char const *zInput){
 static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){
   char *zRet = 0;
   char *zFree = 0;
-  char *zFunction;
+  const char *zFunction;
   int i;
 
   if( p->zContentTbl==0 ){
     if( !zFunc ){
       zFunction = "";
     }else{
-      zFree = zFunction = fts3QuoteId(zFunc);
+      zFunction = zFree = fts3QuoteId(zFunc);
     }
     fts3Appendf(pRc, &zRet, "docid");
     for(i=0; i<p->nColumn; i++){
@@ -139102,13 +141994,13 @@ static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){
 static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
   char *zRet = 0;
   char *zFree = 0;
-  char *zFunction;
+  const char *zFunction;
   int i;
 
   if( !zFunc ){
     zFunction = "";
   }else{
-    zFree = zFunction = fts3QuoteId(zFunc);
+    zFunction = zFree = fts3QuoteId(zFunc);
   }
   fts3Appendf(pRc, &zRet, "?");
   for(i=0; i<p->nColumn; i++){
@@ -145085,7 +147977,7 @@ static int getNextNode(
   int *pnConsumed                         /* OUT: Number of bytes consumed */
 ){
   static const struct Fts3Keyword {
-    char *z;                              /* Keyword text */
+    const char *z;                        /* Keyword text */
     unsigned char n;                      /* Length of the keyword */
     unsigned char parenOnly;              /* Only valid in paren mode */
     unsigned char eType;                  /* Keyword code */
@@ -147081,6 +149973,18 @@ SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(
 /* #include <string.h> */
 
 /*
+** Return true if the two-argument version of fts3_tokenizer()
+** has been activated via a prior call to sqlite3_db_config(db,
+** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
+*/
+static int fts3TokenizerEnabled(sqlite3_context *context){
+  sqlite3 *db = sqlite3_context_db_handle(context);
+  int isEnabled = 0;
+  sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled);
+  return isEnabled;
+}
+
+/*
 ** Implementation of the SQL scalar function for accessing the underlying 
 ** hash table. This function may be called as follows:
 **
@@ -147100,7 +150004,7 @@ SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(
 ** is a blob containing the pointer stored as the hash data corresponding
 ** to string <key-name> (after the hash-table is updated, if applicable).
 */
-static void scalarFunc(
+static void fts3TokenizerFunc(
   sqlite3_context *context,
   int argc,
   sqlite3_value **argv
@@ -147118,27 +150022,23 @@ static void scalarFunc(
   nName = sqlite3_value_bytes(argv[0])+1;
 
   if( argc==2 ){
-#ifdef SQLITE_ENABLE_FTS3_TOKENIZER
-    void *pOld;
-    int n = sqlite3_value_bytes(argv[1]);
-    if( zName==0 || n!=sizeof(pPtr) ){
-      sqlite3_result_error(context, "argument type mismatch", -1);
-      return;
-    }
-    pPtr = *(void **)sqlite3_value_blob(argv[1]);
-    pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
-    if( pOld==pPtr ){
-      sqlite3_result_error(context, "out of memory", -1);
+    if( fts3TokenizerEnabled(context) ){
+      void *pOld;
+      int n = sqlite3_value_bytes(argv[1]);
+      if( zName==0 || n!=sizeof(pPtr) ){
+        sqlite3_result_error(context, "argument type mismatch", -1);
+        return;
+      }
+      pPtr = *(void **)sqlite3_value_blob(argv[1]);
+      pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
+      if( pOld==pPtr ){
+        sqlite3_result_error(context, "out of memory", -1);
+      }
+    }else{
+      sqlite3_result_error(context, "fts3tokenize disabled", -1);
       return;
     }
-#else
-    sqlite3_result_error(context, "fts3tokenize: " 
-        "disabled - rebuild with -DSQLITE_ENABLE_FTS3_TOKENIZER", -1
-    );
-    return;
-#endif /* SQLITE_ENABLE_FTS3_TOKENIZER */
-  }else
-  {
+  }else{
     if( zName ){
       pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
     }
@@ -147149,7 +150049,6 @@ static void scalarFunc(
       return;
     }
   }
-
   sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
 }
 
@@ -147387,7 +150286,6 @@ finish:
   Tcl_DecrRefCount(pRet);
 }
 
-#ifdef SQLITE_ENABLE_FTS3_TOKENIZER
 static
 int registerTokenizer(
   sqlite3 *db, 
@@ -147409,7 +150307,6 @@ int registerTokenizer(
 
   return sqlite3_finalize(pStmt);
 }
-#endif /* SQLITE_ENABLE_FTS3_TOKENIZER */
 
 
 static
@@ -147482,13 +150379,13 @@ static void intTestFunc(
   assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") );
 
   /* Test the storage function */
-#ifdef SQLITE_ENABLE_FTS3_TOKENIZER
-  rc = registerTokenizer(db, "nosuchtokenizer", p1);
-  assert( rc==SQLITE_OK );
-  rc = queryTokenizer(db, "nosuchtokenizer", &p2);
-  assert( rc==SQLITE_OK );
-  assert( p2==p1 );
-#endif
+  if( fts3TokenizerEnabled(context) ){
+    rc = registerTokenizer(db, "nosuchtokenizer", p1);
+    assert( rc==SQLITE_OK );
+    rc = queryTokenizer(db, "nosuchtokenizer", &p2);
+    assert( rc==SQLITE_OK );
+    assert( p2==p1 );
+  }
 
   sqlite3_result_text(context, "ok", -1, SQLITE_STATIC);
 }
@@ -147504,7 +150401,7 @@ static void intTestFunc(
 **    sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
 **
 ** This function adds a scalar function (see header comment above
-** scalarFunc() in this file for details) and, if ENABLE_TABLE is
+** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is
 ** defined at compilation time, a temporary virtual table (see header 
 ** comment above struct HashTableVtab) to the database schema. Both 
 ** provide read/write access to the contents of *pHash.
@@ -147533,10 +150430,10 @@ SQLITE_PRIVATE int sqlite3Fts3InitHashTable(
 #endif
 
   if( SQLITE_OK==rc ){
-    rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0);
+    rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0);
   }
   if( SQLITE_OK==rc ){
-    rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0);
+    rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0);
   }
 #ifdef SQLITE_TEST
   if( SQLITE_OK==rc ){
@@ -148588,7 +151485,8 @@ static int fts3SqlStmt(
 ** of the oldest level in the db that contains at least ? segments. Or,
 ** if no level in the FTS index contains more than ? segments, the statement
 ** returns zero rows.  */
-/* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?"
+/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' "
+         "  GROUP BY level HAVING cnt>=?"
          "  ORDER BY (level %% 1024) ASC LIMIT 1",
 
 /* Estimate the upper limit on the number of leaf nodes in a new segment
@@ -151449,7 +154347,7 @@ static int fts3SegmentMerge(
     ** segment. The level of the new segment is equal to the numerically
     ** greatest segment level currently present in the database for this
     ** index. The idx of the new segment is always 0.  */
-    if( csr.nSegment==1 ){
+    if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){
       rc = SQLITE_DONE;
       goto finished;
     }
@@ -153091,10 +155989,11 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
     ** set nSeg to -1.
     */
     rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0);
-    sqlite3_bind_int(pFindLevel, 1, nMin);
+    sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin));
     if( sqlite3_step(pFindLevel)==SQLITE_ROW ){
       iAbsLevel = sqlite3_column_int64(pFindLevel, 0);
-      nSeg = nMin;
+      nSeg = sqlite3_column_int(pFindLevel, 1);
+      assert( nSeg>=2 );
     }else{
       nSeg = -1;
     }
@@ -158168,7 +161067,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
     return SQLITE_NOMEM;
   }
 
-  nRow = pRtree->nRowEst / (iIdx + 1);
+  nRow = pRtree->nRowEst >> (iIdx/2);
   pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
   setEstimatedRows(pIdxInfo, nRow);
 
@@ -160003,6 +162902,38 @@ static void xFree(void *p){
 }
 
 /*
+** This lookup table is used to help decode the first byte of
+** a multi-byte UTF8 character. It is copied here from SQLite source
+** code file utf8.c.
+*/
+static const unsigned char icuUtf8Trans1[] = {
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
+};
+
+#define SQLITE_ICU_READ_UTF8(zIn, c)                       \
+  c = *(zIn++);                                            \
+  if( c>=0xc0 ){                                           \
+    c = icuUtf8Trans1[c-0xc0];                             \
+    while( (*zIn & 0xc0)==0x80 ){                          \
+      c = (c<<6) + (0x3f & *(zIn++));                      \
+    }                                                      \
+  }
+
+#define SQLITE_ICU_SKIP_UTF8(zIn)                          \
+  assert( *zIn );                                          \
+  if( *(zIn++)>=0xc0 ){                                    \
+    while( (*zIn & 0xc0)==0x80 ){zIn++;}                   \
+  }
+
+
+/*
 ** Compare two UTF-8 strings for equality where the first string is
 ** a "LIKE" expression. Return true (1) if they are the same and 
 ** false (0) if they are different.
@@ -160015,16 +162946,14 @@ static int icuLikeCompare(
   static const int MATCH_ONE = (UChar32)'_';
   static const int MATCH_ALL = (UChar32)'%';
 
-  int iPattern = 0;       /* Current byte index in zPattern */
-  int iString = 0;        /* Current byte index in zString */
-
   int prevEscape = 0;     /* True if the previous character was uEsc */
 
-  while( zPattern[iPattern]!=0 ){
+  while( 1 ){
 
     /* Read (and consume) the next character from the input pattern. */
     UChar32 uPattern;
-    U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
+    SQLITE_ICU_READ_UTF8(zPattern, uPattern);
+    if( uPattern==0 ) break;
 
     /* There are now 4 possibilities:
     **
@@ -160041,28 +162970,28 @@ static int icuLikeCompare(
       ** MATCH_ALL. For each MATCH_ONE, skip one character in the 
       ** test string.
       */
-      while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
+      while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){
         if( c==MATCH_ONE ){
-          if( zString[iString]==0 ) return 0;
-          U8_FWD_1_UNSAFE(zString, iString);
+          if( *zString==0 ) return 0;
+          SQLITE_ICU_SKIP_UTF8(zString);
         }
-        iPattern++;
+        zPattern++;
       }
 
-      if( zPattern[iPattern]==0 ) return 1;
+      if( *zPattern==0 ) return 1;
 
-      while( zString[iString] ){
-        if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
+      while( *zString ){
+        if( icuLikeCompare(zPattern, zString, uEsc) ){
           return 1;
         }
-        U8_FWD_1_UNSAFE(zString, iString);
+        SQLITE_ICU_SKIP_UTF8(zString);
       }
       return 0;
 
     }else if( !prevEscape && uPattern==MATCH_ONE ){
       /* Case 2. */
-      if( zString[iString]==0 ) return 0;
-      U8_FWD_1_UNSAFE(zString, iString);
+      if( *zString==0 ) return 0;
+      SQLITE_ICU_SKIP_UTF8(zString);
 
     }else if( !prevEscape && uPattern==uEsc){
       /* Case 3. */
@@ -160071,7 +163000,7 @@ static int icuLikeCompare(
     }else{
       /* Case 4. */
       UChar32 uString;
-      U8_NEXT_UNSAFE(zString, iString, uString);
+      SQLITE_ICU_READ_UTF8(zString, uString);
       uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
       uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
       if( uString!=uPattern ){
@@ -160081,7 +163010,7 @@ static int icuLikeCompare(
     }
   }
 
-  return zString[iString]==0;
+  return *zString==0;
 }
 
 /*
@@ -160266,15 +163195,17 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
 ** http://www.icu-project.org/userguide/posix.html#case_mappings
 */
 static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
-  const UChar *zInput;
-  UChar *zOutput;
-  int nInput;
-  int nOutput;
-
-  UErrorCode status = U_ZERO_ERROR;
+  const UChar *zInput;            /* Pointer to input string */
+  UChar *zOutput = 0;             /* Pointer to output buffer */
+  int nInput;                     /* Size of utf-16 input string in bytes */
+  int nOut;                       /* Size of output buffer in bytes */
+  int cnt;
+  int bToUpper;                   /* True for toupper(), false for tolower() */
+  UErrorCode status;
   const char *zLocale = 0;
 
   assert(nArg==1 || nArg==2);
+  bToUpper = (sqlite3_user_data(p)!=0);
   if( nArg==2 ){
     zLocale = (const char *)sqlite3_value_text(apArg[1]);
   }
@@ -160283,26 +163214,38 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
   if( !zInput ){
     return;
   }
-  nInput = sqlite3_value_bytes16(apArg[0]);
-
-  nOutput = nInput * 2 + 2;
-  zOutput = sqlite3_malloc(nOutput);
-  if( !zOutput ){
+  nOut = nInput = sqlite3_value_bytes16(apArg[0]);
+  if( nOut==0 ){
+    sqlite3_result_text16(p, "", 0, SQLITE_STATIC);
     return;
   }
 
-  if( sqlite3_user_data(p) ){
-    u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
-  }else{
-    u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
-  }
+  for(cnt=0; cnt<2; cnt++){
+    UChar *zNew = sqlite3_realloc(zOutput, nOut);
+    if( zNew==0 ){
+      sqlite3_free(zOutput);
+      sqlite3_result_error_nomem(p);
+      return;
+    }
+    zOutput = zNew;
+    status = U_ZERO_ERROR;
+    if( bToUpper ){
+      nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
+    }else{
+      nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
+    }
 
-  if( !U_SUCCESS(status) ){
-    icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
+    if( U_SUCCESS(status) ){
+      sqlite3_result_text16(p, zOutput, nOut, xFree);
+    }else if( status==U_BUFFER_OVERFLOW_ERROR ){
+      assert( cnt==0 );
+      continue;
+    }else{
+      icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status);
+    }
     return;
   }
-
-  sqlite3_result_text16(p, zOutput, -1, xFree);
+  assert( 0 );     /* Unreachable */
 }
 
 /*
@@ -161120,6 +164063,38 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
 );
 
 /*
+** Open an RBU handle to perform an RBU vacuum on database file zTarget.
+** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
+** that it can be suspended and resumed like an RBU update.
+**
+** The second argument to this function, which may not be NULL, identifies 
+** a database in which to store the state of the RBU vacuum operation if
+** it is suspended. The first time sqlite3rbu_vacuum() is called, to start
+** an RBU vacuum operation, the state database should either not exist or
+** be empty (contain no tables). If an RBU vacuum is suspended by calling
+** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
+** returned SQLITE_DONE, the vacuum state is stored in the state database. 
+** The vacuum can be resumed by calling this function to open a new RBU
+** handle specifying the same target and state databases.
+**
+** This function does not delete the state database after an RBU vacuum
+** is completed, even if it created it. However, if the call to
+** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
+** of the state tables within the state database are zeroed. This way,
+** the next call to sqlite3rbu_vacuum() opens a handle that starts a 
+** new RBU vacuum operation.
+**
+** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
+** describing the sqlite3rbu_create_vfs() API function below for 
+** a description of the complications associated with using RBU with 
+** zipvfs databases.
+*/
+SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
+  const char *zTarget, 
+  const char *zState
+);
+
+/*
 ** Internally, each RBU connection uses a separate SQLite database 
 ** connection to access the target and rbu update databases. This
 ** API allows the application direct access to these database handles.
@@ -161206,6 +164181,48 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg
 SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu);
 
 /*
+** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) 
+** progress indications for the two stages of an RBU update. This API may
+** be useful for driving GUI progress indicators and similar.
+**
+** An RBU update is divided into two stages:
+**
+**   * Stage 1, in which changes are accumulated in an oal/wal file, and
+**   * Stage 2, in which the contents of the wal file are copied into the
+**     main database.
+**
+** The update is visible to non-RBU clients during stage 2. During stage 1
+** non-RBU reader clients may see the original database.
+**
+** If this API is called during stage 2 of the update, output variable 
+** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo)
+** to a value between 0 and 10000 to indicate the permyriadage progress of
+** stage 2. A value of 5000 indicates that stage 2 is half finished, 
+** 9000 indicates that it is 90% finished, and so on.
+**
+** If this API is called during stage 1 of the update, output variable 
+** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The
+** value to which (*pnOne) is set depends on whether or not the RBU 
+** database contains an "rbu_count" table. The rbu_count table, if it 
+** exists, must contain the same columns as the following:
+**
+**   CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
+**
+** There must be one row in the table for each source (data_xxx) table within
+** the RBU database. The 'tbl' column should contain the name of the source
+** table. The 'cnt' column should contain the number of rows within the
+** source table.
+**
+** If the rbu_count table is present and populated correctly and this
+** API is called during stage 1, the *pnOne output variable is set to the
+** permyriadage progress of the same stage. If the rbu_count table does
+** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count
+** table exists but is not correctly populated, the value of the *pnOne
+** output variable during stage 1 is undefined.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo);
+
+/*
 ** Create an RBU VFS named zName that accesses the underlying file-system
 ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, 
 ** then the new RBU VFS uses the default system VFS to access the file-system.
@@ -161326,14 +164343,15 @@ SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName);
 ** RBU_STATE_OALSZ:
 **   Valid if STAGE==1. The size in bytes of the *-oal file.
 */
-#define RBU_STATE_STAGE       1
-#define RBU_STATE_TBL         2
-#define RBU_STATE_IDX         3
-#define RBU_STATE_ROW         4
-#define RBU_STATE_PROGRESS    5
-#define RBU_STATE_CKPT        6
-#define RBU_STATE_COOKIE      7
-#define RBU_STATE_OALSZ       8
+#define RBU_STATE_STAGE        1
+#define RBU_STATE_TBL          2
+#define RBU_STATE_IDX          3
+#define RBU_STATE_ROW          4
+#define RBU_STATE_PROGRESS     5
+#define RBU_STATE_CKPT         6
+#define RBU_STATE_COOKIE       7
+#define RBU_STATE_OALSZ        8
+#define RBU_STATE_PHASEONESTEP 9
 
 #define RBU_STAGE_OAL         1
 #define RBU_STAGE_MOVE        2
@@ -161354,6 +164372,7 @@ typedef struct RbuUpdateStmt RbuUpdateStmt;
 
 #if !defined(SQLITE_AMALGAMATION)
 typedef unsigned int u32;
+typedef unsigned short u16;
 typedef unsigned char u8;
 typedef sqlite3_int64 i64;
 #endif
@@ -161367,6 +164386,8 @@ typedef sqlite3_int64 i64;
 #define WAL_LOCK_CKPT   1
 #define WAL_LOCK_READ0  3
 
+#define SQLITE_FCNTL_RBUCNT    5149216
+
 /*
 ** A structure to store values read from the rbu_state table in memory.
 */
@@ -161379,6 +164400,7 @@ struct RbuState {
   i64 nProgress;
   u32 iCookie;
   i64 iOalSz;
+  i64 nPhaseOneStep;
 };
 
 struct RbuUpdateStmt {
@@ -161423,6 +164445,7 @@ struct RbuObjIter {
   int iTnum;                      /* Root page of current object */
   int iPkTnum;                    /* If eType==EXTERNAL, root of PK index */
   int bUnique;                    /* Current index is unique */
+  int nIndex;                     /* Number of aux. indexes on table zTbl */
 
   /* Statements created by rbuObjIterPrepareAll() */
   int nCol;                       /* Number of columns in current object */
@@ -161459,10 +164482,11 @@ struct RbuObjIter {
 */
 #define RBU_INSERT     1          /* Insert on a main table b-tree */
 #define RBU_DELETE     2          /* Delete a row from a main table b-tree */
-#define RBU_IDX_DELETE 3          /* Delete a row from an aux. index b-tree */
-#define RBU_IDX_INSERT 4          /* Insert on an aux. index b-tree */
-#define RBU_UPDATE     5          /* Update a row in a main table b-tree */
+#define RBU_REPLACE    3          /* Delete and then insert a row */
+#define RBU_IDX_DELETE 4          /* Delete a row from an aux. index b-tree */
+#define RBU_IDX_INSERT 5          /* Insert on an aux. index b-tree */
 
+#define RBU_UPDATE     6          /* Update a row in a main table b-tree */
 
 /*
 ** A single step of an incremental checkpoint - frame iWalFrame of the wal
@@ -161475,6 +164499,43 @@ struct RbuFrame {
 
 /*
 ** RBU handle.
+**
+** nPhaseOneStep:
+**   If the RBU database contains an rbu_count table, this value is set to
+**   a running estimate of the number of b-tree operations required to 
+**   finish populating the *-oal file. This allows the sqlite3_bp_progress()
+**   API to calculate the permyriadage progress of populating the *-oal file
+**   using the formula:
+**
+**     permyriadage = (10000 * nProgress) / nPhaseOneStep
+**
+**   nPhaseOneStep is initialized to the sum of:
+**
+**     nRow * (nIndex + 1)
+**
+**   for all source tables in the RBU database, where nRow is the number
+**   of rows in the source table and nIndex the number of indexes on the
+**   corresponding target database table.
+**
+**   This estimate is accurate if the RBU update consists entirely of
+**   INSERT operations. However, it is inaccurate if:
+**
+**     * the RBU update contains any UPDATE operations. If the PK specified
+**       for an UPDATE operation does not exist in the target table, then
+**       no b-tree operations are required on index b-trees. Or if the 
+**       specified PK does exist, then (nIndex*2) such operations are
+**       required (one delete and one insert on each index b-tree).
+**
+**     * the RBU update contains any DELETE operations for which the specified
+**       PK does not exist. In this case no operations are required on index
+**       b-trees.
+**
+**     * the RBU update contains REPLACE operations. These are similar to
+**       UPDATE operations.
+**
+**   nPhaseOneStep is updated to account for the conditions above during the
+**   first pass of each source table. The updated nPhaseOneStep value is
+**   stored in the rbu_state table if the RBU update is suspended.
 */
 struct sqlite3rbu {
   int eStage;                     /* Value of RBU_STATE_STAGE field */
@@ -161492,6 +164553,7 @@ struct sqlite3rbu {
   const char *zVfsName;           /* Name of automatically created rbu vfs */
   rbu_file *pTargetFd;            /* File handle open on target db */
   i64 iOalSz;
+  i64 nPhaseOneStep;
 
   /* The following state variables are used as part of the incremental
   ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
@@ -161504,6 +164566,10 @@ struct sqlite3rbu {
   int pgsz;
   u8 *aBuf;
   i64 iWalCksum;
+
+  /* Used in RBU vacuum mode only */
+  int nRbu;                       /* Number of RBU VFS in the stack */
+  rbu_file *pRbuFd;               /* Fd for main db of dbRbu */
 };
 
 /*
@@ -161529,6 +164595,7 @@ struct rbu_file {
   int openFlags;                  /* Flags this file was opened with */
   u32 iCookie;                    /* Cookie value for main db files */
   u8 iWriteVer;                   /* "write-version" value for main db files */
+  u8 bNolock;                     /* True to fail EXCLUSIVE locks */
 
   int nShm;                       /* Number of entries in apShm[] array */
   char **apShm;                   /* Array of mmap'd *-shm regions */
@@ -161539,6 +164606,11 @@ struct rbu_file {
   rbu_file *pMainNext;            /* Next MAIN_DB file */
 };
 
+/*
+** True for an RBU vacuum handle, or false otherwise.
+*/
+#define rbuIsVacuum(p) ((p)->zTarget==0)
+
 
 /*************************************************************************
 ** The following three functions, found below:
@@ -161987,8 +165059,11 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){
 
 /*
 ** The implementation of the rbu_target_name() SQL function. This function
-** accepts one argument - the name of a table in the RBU database. If the
-** table name matches the pattern:
+** accepts one or two arguments. The first argument is the name of a table -
+** the name of a table in the RBU database.  The second, if it is present, is 1
+** for a view or 0 for a table. 
+**
+** For a non-vacuum RBU handle, if the table name matches the pattern:
 **
 **     data[0-9]_<name>
 **
@@ -161999,21 +165074,33 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){
 **     "data_t1"     -> "t1"
 **     "data0123_t2" -> "t2"
 **     "dataAB_t3"   -> NULL
+**
+** For an rbu vacuum handle, a copy of the first argument is returned if
+** the second argument is either missing or 0 (not a view).
 */
 static void rbuTargetNameFunc(
-  sqlite3_context *context,
+  sqlite3_context *pCtx,
   int argc,
   sqlite3_value **argv
 ){
+  sqlite3rbu *p = sqlite3_user_data(pCtx);
   const char *zIn;
-  assert( argc==1 );
+  assert( argc==1 || argc==2 );
 
   zIn = (const char*)sqlite3_value_text(argv[0]);
-  if( zIn && strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
-    int i;
-    for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
-    if( zIn[i]=='_' && zIn[i+1] ){
-      sqlite3_result_text(context, &zIn[i+1], -1, SQLITE_STATIC);
+  if( zIn ){
+    if( rbuIsVacuum(p) ){
+      if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
+        sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
+      }
+    }else{
+      if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
+        int i;
+        for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
+        if( zIn[i]=='_' && zIn[i+1] ){
+          sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC);
+        }
+      }
     }
   }
 }
@@ -162031,7 +165118,8 @@ static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
   memset(pIter, 0, sizeof(RbuObjIter));
 
   rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, 
-      "SELECT rbu_target_name(name) AS target, name FROM sqlite_master "
+      "SELECT rbu_target_name(name, type='view') AS target, name "
+      "FROM sqlite_master "
       "WHERE type IN ('table', 'view') AND target IS NOT NULL "
       "ORDER BY name"
   );
@@ -162322,6 +165410,7 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
     );
   }
 
+  pIter->nIndex = 0;
   while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
     const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
     sqlite3_stmt *pXInfo = 0;
@@ -162335,6 +165424,12 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
     }
     rbuFinalize(p, pXInfo);
     bIndex = 1;
+    pIter->nIndex++;
+  }
+
+  if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
+    /* "PRAGMA index_list" includes the main PK b-tree */
+    pIter->nIndex--;
   }
 
   rbuFinalize(p, pList);
@@ -162400,6 +165495,7 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
     pStmt = 0;
 
     if( p->rc==SQLITE_OK
+     && rbuIsVacuum(p)==0
      && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
     ){
       p->rc = SQLITE_ERROR;
@@ -162448,6 +165544,7 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
     rbuFinalize(p, pStmt);
     rbuObjIterCacheIndexedCols(p, pIter);
     assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 );
+    assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 );
   }
 
   return p->rc;
@@ -162538,6 +165635,8 @@ static char *rbuObjIterGetIndexCols(
         for(i=0; pIter->abTblPk[i]==0; i++);
         assert( i<pIter->nTblCol );
         zCol = pIter->azTblCol[i];
+      }else if( rbuIsVacuum(p) ){
+        zCol = "_rowid_";
       }else{
         zCol = "rbu_rowid";
       }
@@ -163001,6 +166100,14 @@ static void rbuTmpInsertFunc(
   int rc = SQLITE_OK;
   int i;
 
+  assert( sqlite3_value_int(apVal[0])!=0
+      || p->objiter.eType==RBU_PK_EXTERNAL 
+      || p->objiter.eType==RBU_PK_NONE 
+  );
+  if( sqlite3_value_int(apVal[0])!=0 ){
+    p->nPhaseOneStep += p->objiter.nIndex;
+  }
+
   for(i=0; rc==SQLITE_OK && i<nVal; i++){
     rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
   }
@@ -163070,7 +166177,7 @@ static int rbuObjIterPrepareAll(
       }
 
       /* And to delete index entries */
-      if( p->rc==SQLITE_OK ){
+      if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
         p->rc = prepareFreeAndCollectError(
             p->dbMain, &pIter->pDelete, &p->zErrmsg,
           sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere)
@@ -163080,6 +166187,15 @@ static int rbuObjIterPrepareAll(
       /* Create the SELECT statement to read keys in sorted order */
       if( p->rc==SQLITE_OK ){
         char *zSql;
+        if( rbuIsVacuum(p) ){
+          zSql = sqlite3_mprintf(
+              "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s",
+              zCollist, 
+              pIter->zDataTbl,
+              zCollist, zLimit
+          );
+        }else
+
         if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
           zSql = sqlite3_mprintf(
               "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
@@ -163088,13 +166204,13 @@ static int rbuObjIterPrepareAll(
           );
         }else{
           zSql = sqlite3_mprintf(
+              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
+              "UNION ALL "
               "SELECT %s, rbu_control FROM '%q' "
               "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
-              "UNION ALL "
-              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
               "ORDER BY %s%s",
-              zCollist, pIter->zDataTbl, 
               zCollist, p->zStateDb, pIter->zDataTbl, 
+              zCollist, pIter->zDataTbl, 
               zCollist, zLimit
           );
         }
@@ -163106,7 +166222,9 @@ static int rbuObjIterPrepareAll(
       sqlite3_free(zWhere);
       sqlite3_free(zBind);
     }else{
-      int bRbuRowid = (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE);
+      int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
+                    ||(pIter->eType==RBU_PK_NONE)
+                    ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p));
       const char *zTbl = pIter->zTbl;       /* Table this step applies to */
       const char *zWrite;                   /* Imposter table name */
 
@@ -163133,8 +166251,10 @@ static int rbuObjIterPrepareAll(
         );
       }
 
-      /* Create the DELETE statement to write to the target PK b-tree */
-      if( p->rc==SQLITE_OK ){
+      /* Create the DELETE statement to write to the target PK b-tree.
+      ** Because it only performs INSERT operations, this is not required for
+      ** an rbu vacuum handle.  */
+      if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
         p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
             sqlite3_mprintf(
               "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
@@ -163142,7 +166262,7 @@ static int rbuObjIterPrepareAll(
         );
       }
 
-      if( pIter->abIndexed ){
+      if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
         const char *zRbuRowid = "";
         if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
           zRbuRowid = ", rbu_rowid";
@@ -163160,17 +166280,17 @@ static int rbuObjIterPrepareAll(
         rbuMPrintfExec(p, p->dbMain,
             "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" "
             "BEGIN "
-            "  SELECT rbu_tmp_insert(2, %s);"
+            "  SELECT rbu_tmp_insert(3, %s);"
             "END;"
 
             "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" "
             "BEGIN "
-            "  SELECT rbu_tmp_insert(2, %s);"
+            "  SELECT rbu_tmp_insert(3, %s);"
             "END;"
 
             "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" "
             "BEGIN "
-            "  SELECT rbu_tmp_insert(3, %s);"
+            "  SELECT rbu_tmp_insert(4, %s);"
             "END;",
             zWrite, zTbl, zOldlist,
             zWrite, zTbl, zOldlist,
@@ -163192,10 +166312,16 @@ static int rbuObjIterPrepareAll(
 
       /* Create the SELECT statement to read keys from data_xxx */
       if( p->rc==SQLITE_OK ){
+        const char *zRbuRowid = "";
+        if( bRbuRowid ){
+          zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
+        }
         p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
             sqlite3_mprintf(
-              "SELECT %s, rbu_control%s FROM '%q'%s", 
-              zCollist, (bRbuRowid ? ", rbu_rowid" : ""), 
+              "SELECT %s,%s rbu_control%s FROM '%q'%s", 
+              zCollist, 
+              (rbuIsVacuum(p) ? "0 AS " : ""),
+              zRbuRowid,
               pIter->zDataTbl, zLimit
             )
         );
@@ -163290,11 +166416,15 @@ static int rbuGetUpdateStmt(
   return p->rc;
 }
 
-static sqlite3 *rbuOpenDbhandle(sqlite3rbu *p, const char *zName){
+static sqlite3 *rbuOpenDbhandle(
+  sqlite3rbu *p, 
+  const char *zName, 
+  int bUseVfs
+){
   sqlite3 *db = 0;
   if( p->rc==SQLITE_OK ){
     const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
-    p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName);
+    p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0);
     if( p->rc ){
       p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
       sqlite3_close(db);
@@ -163305,16 +166435,109 @@ static sqlite3 *rbuOpenDbhandle(sqlite3rbu *p, const char *zName){
 }
 
 /*
+** Free an RbuState object allocated by rbuLoadState().
+*/
+static void rbuFreeState(RbuState *p){
+  if( p ){
+    sqlite3_free(p->zTbl);
+    sqlite3_free(p->zIdx);
+    sqlite3_free(p);
+  }
+}
+
+/*
+** Allocate an RbuState object and load the contents of the rbu_state 
+** table into it. Return a pointer to the new object. It is the 
+** responsibility of the caller to eventually free the object using
+** sqlite3_free().
+**
+** If an error occurs, leave an error code and message in the rbu handle
+** and return NULL.
+*/
+static RbuState *rbuLoadState(sqlite3rbu *p){
+  RbuState *pRet = 0;
+  sqlite3_stmt *pStmt = 0;
+  int rc;
+  int rc2;
+
+  pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
+  if( pRet==0 ) return 0;
+
+  rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, 
+      sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
+  );
+  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+    switch( sqlite3_column_int(pStmt, 0) ){
+      case RBU_STATE_STAGE:
+        pRet->eStage = sqlite3_column_int(pStmt, 1);
+        if( pRet->eStage!=RBU_STAGE_OAL
+         && pRet->eStage!=RBU_STAGE_MOVE
+         && pRet->eStage!=RBU_STAGE_CKPT
+        ){
+          p->rc = SQLITE_CORRUPT;
+        }
+        break;
+
+      case RBU_STATE_TBL:
+        pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+        break;
+
+      case RBU_STATE_IDX:
+        pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+        break;
+
+      case RBU_STATE_ROW:
+        pRet->nRow = sqlite3_column_int(pStmt, 1);
+        break;
+
+      case RBU_STATE_PROGRESS:
+        pRet->nProgress = sqlite3_column_int64(pStmt, 1);
+        break;
+
+      case RBU_STATE_CKPT:
+        pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
+        break;
+
+      case RBU_STATE_COOKIE:
+        pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
+        break;
+
+      case RBU_STATE_OALSZ:
+        pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
+        break;
+
+      case RBU_STATE_PHASEONESTEP:
+        pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
+        break;
+
+      default:
+        rc = SQLITE_CORRUPT;
+        break;
+    }
+  }
+  rc2 = sqlite3_finalize(pStmt);
+  if( rc==SQLITE_OK ) rc = rc2;
+
+  p->rc = rc;
+  return pRet;
+}
+
+
+/*
 ** Open the database handle and attach the RBU database as "rbu". If an
 ** error occurs, leave an error code and message in the RBU handle.
 */
 static void rbuOpenDatabase(sqlite3rbu *p){
   assert( p->rc==SQLITE_OK );
   assert( p->dbMain==0 && p->dbRbu==0 );
+  assert( rbuIsVacuum(p) || p->zTarget!=0 );
 
-  p->eStage = 0;
-  p->dbMain = rbuOpenDbhandle(p, p->zTarget);
-  p->dbRbu = rbuOpenDbhandle(p, p->zRbu);
+  /* Open the RBU database */
+  p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
+
+  if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
+    sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
+  }
 
   /* If using separate RBU and state databases, attach the state database to
   ** the RBU db handle now.  */
@@ -163325,6 +166548,96 @@ static void rbuOpenDatabase(sqlite3rbu *p){
     memcpy(p->zStateDb, "main", 4);
   }
 
+#if 0
+  if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
+    p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0);
+  }
+#endif
+
+  /* If it has not already been created, create the rbu_state table */
+  rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
+
+#if 0
+  if( rbuIsVacuum(p) ){
+    if( p->rc==SQLITE_OK ){
+      int rc2;
+      int bOk = 0;
+      sqlite3_stmt *pCnt = 0;
+      p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg,
+          "SELECT count(*) FROM stat.sqlite_master"
+      );
+      if( p->rc==SQLITE_OK 
+       && sqlite3_step(pCnt)==SQLITE_ROW
+       && 1==sqlite3_column_int(pCnt, 0)
+      ){
+        bOk = 1;
+      }
+      rc2 = sqlite3_finalize(pCnt);
+      if( p->rc==SQLITE_OK ) p->rc = rc2;
+
+      if( p->rc==SQLITE_OK && bOk==0 ){
+        p->rc = SQLITE_ERROR;
+        p->zErrmsg = sqlite3_mprintf("invalid state database");
+      }
+    
+      if( p->rc==SQLITE_OK ){
+        p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
+      }
+    }
+  }
+#endif
+
+  if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
+    int bOpen = 0;
+    int rc;
+    p->nRbu = 0;
+    p->pRbuFd = 0;
+    rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
+    if( rc!=SQLITE_NOTFOUND ) p->rc = rc;
+    if( p->eStage>=RBU_STAGE_MOVE ){
+      bOpen = 1;
+    }else{
+      RbuState *pState = rbuLoadState(p);
+      if( pState ){
+        bOpen = (pState->eStage>RBU_STAGE_MOVE);
+        rbuFreeState(pState);
+      }
+    }
+    if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1);
+  }
+
+  p->eStage = 0;
+  if( p->rc==SQLITE_OK && p->dbMain==0 ){
+    if( !rbuIsVacuum(p) ){
+      p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
+    }else if( p->pRbuFd->pWalFd ){
+      p->rc = SQLITE_ERROR;
+      p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database");
+    }else{
+      char *zTarget;
+      char *zExtra = 0;
+      if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){
+        zExtra = &p->zRbu[5];
+        while( *zExtra ){
+          if( *zExtra++=='?' ) break;
+        }
+        if( *zExtra=='\0' ) zExtra = 0;
+      }
+
+      zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s", 
+          sqlite3_db_filename(p->dbRbu, "main"),
+          (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
+      );
+
+      if( zTarget==0 ){
+        p->rc = SQLITE_NOMEM;
+        return;
+      }
+      p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1);
+      sqlite3_free(zTarget);
+    }
+  }
+
   if( p->rc==SQLITE_OK ){
     p->rc = sqlite3_create_function(p->dbMain, 
         "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0
@@ -163339,7 +166652,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){
 
   if( p->rc==SQLITE_OK ){
     p->rc = sqlite3_create_function(p->dbRbu, 
-        "rbu_target_name", 1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
+        "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
     );
   }
 
@@ -163598,9 +166911,15 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
 */
 static void rbuMoveOalFile(sqlite3rbu *p){
   const char *zBase = sqlite3_db_filename(p->dbMain, "main");
+  const char *zMove = zBase;
+  char *zOal;
+  char *zWal;
 
-  char *zWal = sqlite3_mprintf("%s-wal", zBase);
-  char *zOal = sqlite3_mprintf("%s-oal", zBase);
+  if( rbuIsVacuum(p) ){
+    zMove = sqlite3_db_filename(p->dbRbu, "main");
+  }
+  zOal = sqlite3_mprintf("%s-oal", zMove);
+  zWal = sqlite3_mprintf("%s-wal", zMove);
 
   assert( p->eStage==RBU_STAGE_MOVE );
   assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
@@ -163621,8 +166940,8 @@ static void rbuMoveOalFile(sqlite3rbu *p){
 
       /* Re-open the databases. */
       rbuObjIterFinalize(&p->objiter);
-      sqlite3_close(p->dbMain);
       sqlite3_close(p->dbRbu);
+      sqlite3_close(p->dbMain);
       p->dbMain = 0;
       p->dbRbu = 0;
 
@@ -163688,14 +167007,12 @@ static int rbuStepType(sqlite3rbu *p, const char **pzMask){
   switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
     case SQLITE_INTEGER: {
       int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
-      if( iVal==0 ){
-        res = RBU_INSERT;
-      }else if( iVal==1 ){
-        res = RBU_DELETE;
-      }else if( iVal==2 ){
-        res = RBU_IDX_DELETE;
-      }else if( iVal==3 ){
-        res = RBU_IDX_INSERT;
+      switch( iVal ){
+        case 0: res = RBU_INSERT;     break;
+        case 1: res = RBU_DELETE;     break;
+        case 2: res = RBU_REPLACE;    break;
+        case 3: res = RBU_IDX_DELETE; break;
+        case 4: res = RBU_IDX_INSERT; break;
       }
       break;
     }
@@ -163735,6 +167052,83 @@ static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
 #endif
 
 /*
+** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or
+** RBU_IDX_DELETE. This function performs the work of a single
+** sqlite3rbu_step() call for the type of operation specified by eType.
+*/
+static void rbuStepOneOp(sqlite3rbu *p, int eType){
+  RbuObjIter *pIter = &p->objiter;
+  sqlite3_value *pVal;
+  sqlite3_stmt *pWriter;
+  int i;
+
+  assert( p->rc==SQLITE_OK );
+  assert( eType!=RBU_DELETE || pIter->zIdx==0 );
+  assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE
+       || eType==RBU_INSERT || eType==RBU_IDX_INSERT
+  );
+
+  /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE
+  ** statement below does actually delete a row, nPhaseOneStep will be
+  ** incremented by the same amount when SQL function rbu_tmp_insert()
+  ** is invoked by the trigger.  */
+  if( eType==RBU_DELETE ){
+    p->nPhaseOneStep -= p->objiter.nIndex;
+  }
+
+  if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
+    pWriter = pIter->pDelete;
+  }else{
+    pWriter = pIter->pInsert;
+  }
+
+  for(i=0; i<pIter->nCol; i++){
+    /* If this is an INSERT into a table b-tree and the table has an
+    ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
+    ** to write a NULL into the IPK column. That is not permitted.  */
+    if( eType==RBU_INSERT 
+     && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i] 
+     && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
+    ){
+      p->rc = SQLITE_MISMATCH;
+      p->zErrmsg = sqlite3_mprintf("datatype mismatch");
+      return;
+    }
+
+    if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
+      continue;
+    }
+
+    pVal = sqlite3_column_value(pIter->pSelect, i);
+    p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
+    if( p->rc ) return;
+  }
+  if( pIter->zIdx==0 ){
+    if( pIter->eType==RBU_PK_VTAB 
+     || pIter->eType==RBU_PK_NONE 
+     || (pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p)) 
+    ){
+      /* For a virtual table, or a table with no primary key, the 
+      ** SELECT statement is:
+      **
+      **   SELECT <cols>, rbu_control, rbu_rowid FROM ....
+      **
+      ** Hence column_value(pIter->nCol+1).
+      */
+      assertColumnName(pIter->pSelect, pIter->nCol+1, 
+          rbuIsVacuum(p) ? "rowid" : "rbu_rowid"
+      );
+      pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
+      p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
+    }
+  }
+  if( p->rc==SQLITE_OK ){
+    sqlite3_step(pWriter);
+    p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
+  }
+}
+
+/*
 ** This function does the work for an sqlite3rbu_step() call.
 **
 ** The object-iterator (p->objiter) currently points to a valid object,
@@ -163748,78 +167142,36 @@ static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
 static int rbuStep(sqlite3rbu *p){
   RbuObjIter *pIter = &p->objiter;
   const char *zMask = 0;
-  int i;
   int eType = rbuStepType(p, &zMask);
 
   if( eType ){
+    assert( eType==RBU_INSERT     || eType==RBU_DELETE
+         || eType==RBU_REPLACE    || eType==RBU_IDX_DELETE
+         || eType==RBU_IDX_INSERT || eType==RBU_UPDATE
+    );
     assert( eType!=RBU_UPDATE || pIter->zIdx==0 );
 
-    if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){
+    if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){
       rbuBadControlError(p);
     }
-    else if( 
-        eType==RBU_INSERT 
-     || eType==RBU_DELETE
-     || eType==RBU_IDX_DELETE 
-     || eType==RBU_IDX_INSERT
-    ){
-      sqlite3_value *pVal;
-      sqlite3_stmt *pWriter;
-
-      assert( eType!=RBU_UPDATE );
-      assert( eType!=RBU_DELETE || pIter->zIdx==0 );
-
-      if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
-        pWriter = pIter->pDelete;
-      }else{
-        pWriter = pIter->pInsert;
-      }
-
-      for(i=0; i<pIter->nCol; i++){
-        /* If this is an INSERT into a table b-tree and the table has an
-        ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
-        ** to write a NULL into the IPK column. That is not permitted.  */
-        if( eType==RBU_INSERT 
-         && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i] 
-         && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
-        ){
-          p->rc = SQLITE_MISMATCH;
-          p->zErrmsg = sqlite3_mprintf("datatype mismatch");
-          goto step_out;
-        }
-
-        if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
-          continue;
-        }
-
-        pVal = sqlite3_column_value(pIter->pSelect, i);
-        p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
-        if( p->rc ) goto step_out;
-      }
-      if( pIter->zIdx==0
-       && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) 
-      ){
-        /* For a virtual table, or a table with no primary key, the 
-        ** SELECT statement is:
-        **
-        **   SELECT <cols>, rbu_control, rbu_rowid FROM ....
-        **
-        ** Hence column_value(pIter->nCol+1).
-        */
-        assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
-        pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
-        p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
+    else if( eType==RBU_REPLACE ){
+      if( pIter->zIdx==0 ){
+        p->nPhaseOneStep += p->objiter.nIndex;
+        rbuStepOneOp(p, RBU_DELETE);
       }
-      if( p->rc==SQLITE_OK ){
-        sqlite3_step(pWriter);
-        p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
-      }
-    }else{
+      if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT);
+    }
+    else if( eType!=RBU_UPDATE ){
+      rbuStepOneOp(p, eType);
+    }
+    else{
       sqlite3_value *pVal;
       sqlite3_stmt *pUpdate = 0;
       assert( eType==RBU_UPDATE );
+      p->nPhaseOneStep -= p->objiter.nIndex;
       rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
       if( pUpdate ){
+        int i;
         for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
           char c = zMask[pIter->aiSrcOrder[i]];
           pVal = sqlite3_column_value(pIter->pSelect, i);
@@ -163842,20 +167194,23 @@ static int rbuStep(sqlite3rbu *p){
       }
     }
   }
-
- step_out:
   return p->rc;
 }
 
 /*
 ** Increment the schema cookie of the main database opened by p->dbMain.
+**
+** Or, if this is an RBU vacuum, set the schema cookie of the main db
+** opened by p->dbMain to one more than the schema cookie of the main
+** db opened by p->dbRbu.
 */
 static void rbuIncrSchemaCookie(sqlite3rbu *p){
   if( p->rc==SQLITE_OK ){
+    sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
     int iCookie = 1000000;
     sqlite3_stmt *pStmt;
 
-    p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, 
+    p->rc = prepareAndCollectError(dbread, &pStmt, &p->zErrmsg, 
         "PRAGMA schema_version"
     );
     if( p->rc==SQLITE_OK ){
@@ -163883,6 +167238,7 @@ static void rbuIncrSchemaCookie(sqlite3rbu *p){
 static void rbuSaveState(sqlite3rbu *p, int eStage){
   if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
     sqlite3_stmt *pInsert = 0;
+    rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
     int rc;
 
     assert( p->zErrmsg==0 );
@@ -163896,6 +167252,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
           "(%d, %d), "
           "(%d, %lld), "
           "(%d, %lld), "
+          "(%d, %lld), "
           "(%d, %lld) ",
           p->zStateDb,
           RBU_STATE_STAGE, eStage,
@@ -163904,8 +167261,9 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
           RBU_STATE_ROW, p->nStep, 
           RBU_STATE_PROGRESS, p->nProgress,
           RBU_STATE_CKPT, p->iWalCksum,
-          RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie,
-          RBU_STATE_OALSZ, p->iOalSz
+          RBU_STATE_COOKIE, (i64)pFd->iCookie,
+          RBU_STATE_OALSZ, p->iOalSz,
+          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
       )
     );
     assert( pInsert==0 || rc==SQLITE_OK );
@@ -163920,6 +167278,92 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
 
 
 /*
+** The second argument passed to this function is the name of a PRAGMA 
+** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
+** This function executes the following on sqlite3rbu.dbRbu:
+**
+**   "PRAGMA main.$zPragma"
+**
+** where $zPragma is the string passed as the second argument, then
+** on sqlite3rbu.dbMain:
+**
+**   "PRAGMA main.$zPragma = $val"
+**
+** where $val is the value returned by the first PRAGMA invocation.
+**
+** In short, it copies the value  of the specified PRAGMA setting from
+** dbRbu to dbMain.
+*/
+static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){
+  if( p->rc==SQLITE_OK ){
+    sqlite3_stmt *pPragma = 0;
+    p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg, 
+        sqlite3_mprintf("PRAGMA main.%s", zPragma)
+    );
+    if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){
+      p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d",
+          zPragma, sqlite3_column_int(pPragma, 0)
+      );
+    }
+    rbuFinalize(p, pPragma);
+  }
+}
+
+/*
+** The RBU handle passed as the only argument has just been opened and 
+** the state database is empty. If this RBU handle was opened for an
+** RBU vacuum operation, create the schema in the target db.
+*/
+static void rbuCreateTargetSchema(sqlite3rbu *p){
+  sqlite3_stmt *pSql = 0;
+  sqlite3_stmt *pInsert = 0;
+
+  assert( rbuIsVacuum(p) );
+  p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
+  if( p->rc==SQLITE_OK ){
+    p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, 
+      "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0"
+      " AND name!='sqlite_sequence' "
+      " ORDER BY type DESC"
+    );
+  }
+
+  while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
+    const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
+    p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
+  }
+  rbuFinalize(p, pSql);
+  if( p->rc!=SQLITE_OK ) return;
+
+  if( p->rc==SQLITE_OK ){
+    p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, 
+        "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL" 
+    );
+  }
+
+  if( p->rc==SQLITE_OK ){
+    p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg, 
+        "INSERT INTO sqlite_master VALUES(?,?,?,?,?)"
+    );
+  }
+
+  while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
+    int i;
+    for(i=0; i<5; i++){
+      sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
+    }
+    sqlite3_step(pInsert);
+    p->rc = sqlite3_reset(pInsert);
+  }
+  if( p->rc==SQLITE_OK ){
+    p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg);
+  }
+
+  rbuFinalize(p, pSql);
+  rbuFinalize(p, pInsert);
+}
+
+/*
 ** Step the RBU object.
 */
 SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *p){
@@ -163927,13 +167371,22 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *p){
     switch( p->eStage ){
       case RBU_STAGE_OAL: {
         RbuObjIter *pIter = &p->objiter;
+
+        /* If this is an RBU vacuum operation and the state table was empty
+        ** when this handle was opened, create the target database schema. */
+        if( rbuIsVacuum(p) && p->nProgress==0 && p->rc==SQLITE_OK ){
+          rbuCreateTargetSchema(p);
+          rbuCopyPragma(p, "user_version");
+          rbuCopyPragma(p, "application_id");
+        }
+
         while( p->rc==SQLITE_OK && pIter->zTbl ){
 
           if( pIter->bCleanup ){
             /* Clean up the rbu_tmp_xxx table for the previous table. It 
             ** cannot be dropped as there are currently active SQL statements.
             ** But the contents can be deleted.  */
-            if( pIter->abIndexed ){
+            if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
               rbuMPrintfExec(p, p->dbRbu, 
                   "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl
               );
@@ -164021,90 +167474,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *p){
 }
 
 /*
-** Free an RbuState object allocated by rbuLoadState().
-*/
-static void rbuFreeState(RbuState *p){
-  if( p ){
-    sqlite3_free(p->zTbl);
-    sqlite3_free(p->zIdx);
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Allocate an RbuState object and load the contents of the rbu_state 
-** table into it. Return a pointer to the new object. It is the 
-** responsibility of the caller to eventually free the object using
-** sqlite3_free().
-**
-** If an error occurs, leave an error code and message in the rbu handle
-** and return NULL.
-*/
-static RbuState *rbuLoadState(sqlite3rbu *p){
-  RbuState *pRet = 0;
-  sqlite3_stmt *pStmt = 0;
-  int rc;
-  int rc2;
-
-  pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
-  if( pRet==0 ) return 0;
-
-  rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, 
-      sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
-  );
-  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
-    switch( sqlite3_column_int(pStmt, 0) ){
-      case RBU_STATE_STAGE:
-        pRet->eStage = sqlite3_column_int(pStmt, 1);
-        if( pRet->eStage!=RBU_STAGE_OAL
-         && pRet->eStage!=RBU_STAGE_MOVE
-         && pRet->eStage!=RBU_STAGE_CKPT
-        ){
-          p->rc = SQLITE_CORRUPT;
-        }
-        break;
-
-      case RBU_STATE_TBL:
-        pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
-        break;
-
-      case RBU_STATE_IDX:
-        pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
-        break;
-
-      case RBU_STATE_ROW:
-        pRet->nRow = sqlite3_column_int(pStmt, 1);
-        break;
-
-      case RBU_STATE_PROGRESS:
-        pRet->nProgress = sqlite3_column_int64(pStmt, 1);
-        break;
-
-      case RBU_STATE_CKPT:
-        pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
-        break;
-
-      case RBU_STATE_COOKIE:
-        pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
-        break;
-
-      case RBU_STATE_OALSZ:
-        pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
-        break;
-
-      default:
-        rc = SQLITE_CORRUPT;
-        break;
-    }
-  }
-  rc2 = sqlite3_finalize(pStmt);
-  if( rc==SQLITE_OK ) rc = rc2;
-
-  p->rc = rc;
-  return pRet;
-}
-
-/*
 ** Compare strings z1 and z2, returning 0 if they are identical, or non-zero
 ** otherwise. Either or both argument may be NULL. Two NULL values are
 ** considered equal, and NULL is considered distinct from all other values.
@@ -164200,15 +167569,107 @@ static void rbuDeleteVfs(sqlite3rbu *p){
 }
 
 /*
-** Open and return a new RBU handle. 
+** This user-defined SQL function is invoked with a single argument - the
+** name of a table expected to appear in the target database. It returns
+** the number of auxilliary indexes on the table.
 */
-SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
+static void rbuIndexCntFunc(
+  sqlite3_context *pCtx, 
+  int nVal,
+  sqlite3_value **apVal
+){
+  sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
+  sqlite3_stmt *pStmt = 0;
+  char *zErrmsg = 0;
+  int rc;
+
+  assert( nVal==1 );
+  
+  rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, 
+      sqlite3_mprintf("SELECT count(*) FROM sqlite_master "
+        "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
+  );
+  if( rc!=SQLITE_OK ){
+    sqlite3_result_error(pCtx, zErrmsg, -1);
+  }else{
+    int nIndex = 0;
+    if( SQLITE_ROW==sqlite3_step(pStmt) ){
+      nIndex = sqlite3_column_int(pStmt, 0);
+    }
+    rc = sqlite3_finalize(pStmt);
+    if( rc==SQLITE_OK ){
+      sqlite3_result_int(pCtx, nIndex);
+    }else{
+      sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
+    }
+  }
+
+  sqlite3_free(zErrmsg);
+}
+
+/*
+** If the RBU database contains the rbu_count table, use it to initialize
+** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table
+** is assumed to contain the same columns as:
+**
+**   CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
+**
+** There should be one row in the table for each data_xxx table in the
+** database. The 'tbl' column should contain the name of a data_xxx table,
+** and the cnt column the number of rows it contains.
+**
+** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt
+** for all rows in the rbu_count table, where nIndex is the number of 
+** indexes on the corresponding target database table.
+*/
+static void rbuInitPhaseOneSteps(sqlite3rbu *p){
+  if( p->rc==SQLITE_OK ){
+    sqlite3_stmt *pStmt = 0;
+    int bExists = 0;                /* True if rbu_count exists */
+
+    p->nPhaseOneStep = -1;
+
+    p->rc = sqlite3_create_function(p->dbRbu, 
+        "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0
+    );
+  
+    /* Check for the rbu_count table. If it does not exist, or if an error
+    ** occurs, nPhaseOneStep will be left set to -1. */
+    if( p->rc==SQLITE_OK ){
+      p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
+          "SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'"
+      );
+    }
+    if( p->rc==SQLITE_OK ){
+      if( SQLITE_ROW==sqlite3_step(pStmt) ){
+        bExists = 1;
+      }
+      p->rc = sqlite3_finalize(pStmt);
+    }
+  
+    if( p->rc==SQLITE_OK && bExists ){
+      p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
+          "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))"
+          "FROM rbu_count"
+      );
+      if( p->rc==SQLITE_OK ){
+        if( SQLITE_ROW==sqlite3_step(pStmt) ){
+          p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0);
+        }
+        p->rc = sqlite3_finalize(pStmt);
+      }
+    }
+  }
+}
+
+
+static sqlite3rbu *openRbuHandle(
   const char *zTarget, 
   const char *zRbu,
   const char *zState
 ){
   sqlite3rbu *p;
-  size_t nTarget = strlen(zTarget);
+  size_t nTarget = zTarget ? strlen(zTarget) : 0;
   size_t nRbu = strlen(zRbu);
   size_t nState = zState ? strlen(zState) : 0;
   size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1+ nState+1;
@@ -164221,22 +167682,24 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
     memset(p, 0, sizeof(sqlite3rbu));
     rbuCreateVfs(p);
 
-    /* Open the target database */
+    /* Open the target, RBU and state databases */
     if( p->rc==SQLITE_OK ){
-      p->zTarget = (char*)&p[1];
-      memcpy(p->zTarget, zTarget, nTarget+1);
-      p->zRbu = &p->zTarget[nTarget+1];
+      char *pCsr = (char*)&p[1];
+      if( zTarget ){
+        p->zTarget = pCsr;
+        memcpy(p->zTarget, zTarget, nTarget+1);
+        pCsr += nTarget+1;
+      }
+      p->zRbu = pCsr;
       memcpy(p->zRbu, zRbu, nRbu+1);
+      pCsr += nRbu+1;
       if( zState ){
-        p->zState = &p->zRbu[nRbu+1];
+        p->zState = pCsr;
         memcpy(p->zState, zState, nState+1);
       }
       rbuOpenDatabase(p);
     }
 
-    /* If it has not already been created, create the rbu_state table */
-    rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
-
     if( p->rc==SQLITE_OK ){
       pState = rbuLoadState(p);
       assert( pState || p->rc!=SQLITE_OK );
@@ -164244,9 +167707,11 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
 
         if( pState->eStage==0 ){ 
           rbuDeleteOalFile(p);
+          rbuInitPhaseOneSteps(p);
           p->eStage = RBU_STAGE_OAL;
         }else{
           p->eStage = pState->eStage;
+          p->nPhaseOneStep = pState->nPhaseOneStep;
         }
         p->nProgress = pState->nProgress;
         p->iOalSz = pState->iOalSz;
@@ -164264,27 +167729,39 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
       }
     }
 
-    if( p->rc==SQLITE_OK
+    if( p->rc==SQLITE_OK 
      && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
-     && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
-    ){   
-      /* At this point (pTargetFd->iCookie) contains the value of the
-      ** change-counter cookie (the thing that gets incremented when a 
-      ** transaction is committed in rollback mode) currently stored on 
-      ** page 1 of the database file. */
-      p->rc = SQLITE_BUSY;
-      p->zErrmsg = sqlite3_mprintf("database modified during rbu update");
+     && pState->eStage!=0
+    ){
+      rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
+      if( pFd->iCookie!=pState->iCookie ){   
+        /* At this point (pTargetFd->iCookie) contains the value of the
+        ** change-counter cookie (the thing that gets incremented when a 
+        ** transaction is committed in rollback mode) currently stored on 
+        ** page 1 of the database file. */
+        p->rc = SQLITE_BUSY;
+        p->zErrmsg = sqlite3_mprintf("database modified during rbu %s",
+            (rbuIsVacuum(p) ? "vacuum" : "update")
+        );
+      }
     }
 
     if( p->rc==SQLITE_OK ){
       if( p->eStage==RBU_STAGE_OAL ){
         sqlite3 *db = p->dbMain;
 
+        if( pState->eStage==0 && rbuIsVacuum(p) ){
+          rbuCopyPragma(p, "page_size");
+          rbuCopyPragma(p, "auto_vacuum");
+        }
+
         /* Open transactions both databases. The *-oal file is opened or
         ** created at this point. */
-        p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
         if( p->rc==SQLITE_OK ){
-          p->rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
+          p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
+        }
+        if( p->rc==SQLITE_OK ){
+          p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg);
         }
 
         /* Check if the main database is a zipvfs db. If it is, set the upper
@@ -164329,6 +167806,28 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
   return p;
 }
 
+/*
+** Open and return a new RBU handle. 
+*/
+SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
+  const char *zTarget, 
+  const char *zRbu,
+  const char *zState
+){
+  /* TODO: Check that zTarget and zRbu are non-NULL */
+  return openRbuHandle(zTarget, zRbu, zState);
+}
+
+/*
+** Open a handle to begin or resume an RBU VACUUM operation.
+*/
+SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
+  const char *zTarget, 
+  const char *zState
+){
+  /* TODO: Check that both arguments are non-NULL */
+  return openRbuHandle(0, zTarget, zState);
+}
 
 /*
 ** Return the database handle used by pRbu.
@@ -164349,7 +167848,7 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
 */
 static void rbuEditErrmsg(sqlite3rbu *p){
   if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
-    int i;
+    unsigned int i;
     size_t nErrmsg = strlen(p->zErrmsg);
     for(i=0; i<(nErrmsg-8); i++){
       if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){
@@ -164383,9 +167882,19 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
     /* Close any open statement handles. */
     rbuObjIterFinalize(&p->objiter);
 
+    /* If this is an RBU vacuum handle and the vacuum has either finished
+    ** successfully or encountered an error, delete the contents of the 
+    ** state table. This causes the next call to sqlite3rbu_vacuum() 
+    ** specifying the current target and state databases to start a new
+    ** vacuum from scratch.  */
+    if( rbuIsVacuum(p) && p->rc!=SQLITE_OK && p->dbRbu ){
+      int rc2 = sqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0);
+      if( p->rc==SQLITE_DONE && rc2!=SQLITE_OK ) p->rc = rc2;
+    }
+
     /* Close the open database handle and VFS object. */
-    sqlite3_close(p->dbMain);
     sqlite3_close(p->dbRbu);
+    sqlite3_close(p->dbMain);
     rbuDeleteVfs(p);
     sqlite3_free(p->aBuf);
     sqlite3_free(p->aFrame);
@@ -164410,6 +167919,42 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){
   return pRbu->nProgress;
 }
 
+/*
+** Return permyriadage progress indications for the two main stages of
+** an RBU update.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
+  const int MAX_PROGRESS = 10000;
+  switch( p->eStage ){
+    case RBU_STAGE_OAL:
+      if( p->nPhaseOneStep>0 ){
+        *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep);
+      }else{
+        *pnOne = -1;
+      }
+      *pnTwo = 0;
+      break;
+
+    case RBU_STAGE_MOVE:
+      *pnOne = MAX_PROGRESS;
+      *pnTwo = 0;
+      break;
+
+    case RBU_STAGE_CKPT:
+      *pnOne = MAX_PROGRESS;
+      *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame);
+      break;
+
+    case RBU_STAGE_DONE:
+      *pnOne = MAX_PROGRESS;
+      *pnTwo = MAX_PROGRESS;
+      break;
+
+    default:
+      assert( 0 );
+  }
+}
+
 SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){
   int rc = p->rc;
   
@@ -164552,6 +168097,22 @@ static u32 rbuGetU32(u8 *aBuf){
 }
 
 /*
+** Write an unsigned 32-bit value in big-endian format to the supplied
+** buffer.
+*/
+static void rbuPutU32(u8 *aBuf, u32 iVal){
+  aBuf[0] = (iVal >> 24) & 0xFF;
+  aBuf[1] = (iVal >> 16) & 0xFF;
+  aBuf[2] = (iVal >>  8) & 0xFF;
+  aBuf[3] = (iVal >>  0) & 0xFF;
+}
+
+static void rbuPutU16(u8 *aBuf, u16 iVal){
+  aBuf[0] = (iVal >>  8) & 0xFF;
+  aBuf[1] = (iVal >>  0) & 0xFF;
+}
+
+/*
 ** Read data from an rbuVfs-file.
 */
 static int rbuVfsRead(
@@ -164576,6 +168137,35 @@ static int rbuVfsRead(
       memset(zBuf, 0, iAmt);
     }else{
       rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
+#if 1
+      /* If this is being called to read the first page of the target 
+      ** database as part of an rbu vacuum operation, synthesize the 
+      ** contents of the first page if it does not yet exist. Otherwise,
+      ** SQLite will not check for a *-wal file.  */
+      if( pRbu && rbuIsVacuum(pRbu) 
+          && rc==SQLITE_IOERR_SHORT_READ && iOfst==0
+          && (p->openFlags & SQLITE_OPEN_MAIN_DB)
+          && pRbu->rc==SQLITE_OK
+      ){
+        sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd;
+        rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
+        if( rc==SQLITE_OK ){
+          u8 *aBuf = (u8*)zBuf;
+          u32 iRoot = rbuGetU32(&aBuf[52]) ? 1 : 0;
+          rbuPutU32(&aBuf[52], iRoot);      /* largest root page number */
+          rbuPutU32(&aBuf[36], 0);          /* number of free pages */
+          rbuPutU32(&aBuf[32], 0);          /* first page on free list trunk */
+          rbuPutU32(&aBuf[28], 1);          /* size of db file in pages */
+          rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1);  /* Change counter */
+
+          if( iAmt>100 ){
+            memset(&aBuf[100], 0, iAmt-100);
+            rbuPutU16(&aBuf[105], iAmt & 0xFFFF);
+            aBuf[100] = 0x0D;
+          }
+        }
+      }
+#endif
     }
     if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
       /* These look like magic numbers. But they are stable, as they are part
@@ -164650,7 +168240,20 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){
 */
 static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
   rbu_file *p = (rbu_file *)pFile;
-  return p->pReal->pMethods->xFileSize(p->pReal, pSize);
+  int rc;
+  rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
+
+  /* If this is an RBU vacuum operation and this is the target database,
+  ** pretend that it has at least one page. Otherwise, SQLite will not
+  ** check for the existance of a *-wal file. rbuVfsRead() contains 
+  ** similar logic.  */
+  if( rc==SQLITE_OK && *pSize==0 
+   && p->pRbu && rbuIsVacuum(p->pRbu) 
+   && (p->openFlags & SQLITE_OPEN_MAIN_DB)
+  ){
+    *pSize = 1024;
+  }
+  return rc;
 }
 
 /*
@@ -164662,7 +168265,9 @@ static int rbuVfsLock(sqlite3_file *pFile, int eLock){
   int rc = SQLITE_OK;
 
   assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
-  if( pRbu && eLock==SQLITE_LOCK_EXCLUSIVE && pRbu->eStage!=RBU_STAGE_DONE ){
+  if( eLock==SQLITE_LOCK_EXCLUSIVE 
+   && (p->bNolock || (pRbu && pRbu->eStage!=RBU_STAGE_DONE))
+  ){
     /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this 
     ** prevents it from checkpointing the database from sqlite3_close(). */
     rc = SQLITE_BUSY;
@@ -164725,6 +168330,12 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
     }
     return rc;
   }
+  else if( op==SQLITE_FCNTL_RBUCNT ){
+    sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
+    pRbu->nRbu++;
+    pRbu->pRbuFd = p;
+    p->bNolock = 1;
+  }
 
   rc = xControl(p->pReal, op, pArg);
   if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
@@ -164883,11 +168494,38 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
 static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
   rbu_file *pDb;
   sqlite3_mutex_enter(pRbuVfs->mutex);
-  for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext);
+  for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
   sqlite3_mutex_leave(pRbuVfs->mutex);
   return pDb;
 }
 
+/* 
+** A main database named zName has just been opened. The following 
+** function returns a pointer to a buffer owned by SQLite that contains
+** the name of the *-wal file this db connection will use. SQLite
+** happens to pass a pointer to this buffer when using xAccess()
+** or xOpen() to operate on the *-wal file.  
+*/
+static const char *rbuMainToWal(const char *zName, int flags){
+  int n = (int)strlen(zName);
+  const char *z = &zName[n];
+  if( flags & SQLITE_OPEN_URI ){
+    int odd = 0;
+    while( 1 ){
+      if( z[0]==0 ){
+        odd = 1 - odd;
+        if( odd && z[1]==0 ) break;
+      }
+      z++;
+    }
+    z += 2;
+  }else{
+    while( *z==0 ) z++;
+  }
+  z += (n + 8 + 1);
+  return z;
+}
+
 /*
 ** Open an rbu file handle.
 */
@@ -164923,6 +168561,7 @@ static int rbuVfsOpen(
   rbu_file *pFd = (rbu_file *)pFile;
   int rc = SQLITE_OK;
   const char *zOpen = zName;
+  int oflags = flags;
 
   memset(pFd, 0, sizeof(rbu_file));
   pFd->pReal = (sqlite3_file*)&pFd[1];
@@ -164935,23 +168574,7 @@ static int rbuVfsOpen(
       ** the name of the *-wal file this db connection will use. SQLite
       ** happens to pass a pointer to this buffer when using xAccess()
       ** or xOpen() to operate on the *-wal file.  */
-      int n = (int)strlen(zName);
-      const char *z = &zName[n];
-      if( flags & SQLITE_OPEN_URI ){
-        int odd = 0;
-        while( 1 ){
-          if( z[0]==0 ){
-            odd = 1 - odd;
-            if( odd && z[1]==0 ) break;
-          }
-          z++;
-        }
-        z += 2;
-      }else{
-        while( *z==0 ) z++;
-      }
-      z += (n + 8 + 1);
-      pFd->zWal = z;
+      pFd->zWal = rbuMainToWal(zName, flags);
     }
     else if( flags & SQLITE_OPEN_WAL ){
       rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
@@ -164961,10 +168584,17 @@ static int rbuVfsOpen(
           ** code ensures that the string passed to xOpen() is terminated by a
           ** pair of '\0' bytes in case the VFS attempts to extract a URI 
           ** parameter from it.  */
-          size_t nCopy = strlen(zName);
-          char *zCopy = sqlite3_malloc64(nCopy+2);
+          const char *zBase = zName;
+          size_t nCopy;
+          char *zCopy;
+          if( rbuIsVacuum(pDb->pRbu) ){
+            zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
+            zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI);
+          }
+          nCopy = strlen(zBase);
+          zCopy = sqlite3_malloc64(nCopy+2);
           if( zCopy ){
-            memcpy(zCopy, zName, nCopy);
+            memcpy(zCopy, zBase, nCopy);
             zCopy[nCopy-3] = 'o';
             zCopy[nCopy] = '\0';
             zCopy[nCopy+1] = '\0';
@@ -164979,8 +168609,17 @@ static int rbuVfsOpen(
     }
   }
 
+  if( oflags & SQLITE_OPEN_MAIN_DB 
+   && sqlite3_uri_boolean(zName, "rbu_memory", 0) 
+  ){
+    assert( oflags & SQLITE_OPEN_MAIN_DB );
+    oflags =  SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
+              SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
+    zOpen = 0;
+  }
+
   if( rc==SQLITE_OK ){
-    rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags);
+    rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags);
   }
   if( pFd->pReal->pMethods ){
     /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
@@ -165357,7 +168996,7 @@ struct StatCursor {
   char *zName;                    /* Value of 'name' column */
   char *zPath;                    /* Value of 'path' column */
   u32 iPageno;                    /* Value of 'pageno' column */
-  char *zPagetype;                /* Value of 'pagetype' column */
+  const char *zPagetype;          /* Value of 'pagetype' column */
   int nCell;                      /* Value of 'ncell' column */
   int nPayload;                   /* Value of 'payload' column */
   int nUnused;                    /* Value of 'unused' column */
@@ -165404,7 +169043,7 @@ static int statConnect(
   rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
   if( rc==SQLITE_OK ){
     pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
-    if( pTab==0 ) rc = SQLITE_NOMEM;
+    if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
   }
 
   assert( rc==SQLITE_OK || pTab==0 );
@@ -165485,7 +169124,7 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
 
   pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
   if( pCsr==0 ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }else{
     memset(pCsr, 0, sizeof(StatCursor));
     pCsr->base.pVtab = pVTab;
@@ -165591,7 +169230,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
     nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
     sqlite3BtreeLeave(pBt);
     p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
-    if( p->aCell==0 ) return SQLITE_NOMEM;
+    if( p->aCell==0 ) return SQLITE_NOMEM_BKPT;
     memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
 
     for(i=0; i<p->nCell; i++){
@@ -165624,7 +169263,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
           pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
           pCell->nOvfl = nOvfl;
           pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
-          if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
+          if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
           pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
           for(j=1; j<nOvfl; j++){
             int rc;
@@ -165703,7 +169342,7 @@ statNextRestart:
       pCsr->aPage[0].iCell = 0;
       pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
       pCsr->iPage = 0;
-      if( z==0 ) rc = SQLITE_NOMEM;
+      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
     }else{
       pCsr->isEof = 1;
       return sqlite3_reset(pCsr->pStmt);
@@ -165738,7 +169377,7 @@ statNextRestart:
         }
         pCell->iOvfl++;
         statSizeAndOffset(pCsr);
-        return z==0 ? SQLITE_NOMEM : SQLITE_OK;
+        return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
       }
       if( p->iRightChildPg ) break;
       p->iCell++;
@@ -165762,7 +169401,7 @@ statNextRestart:
     p[1].iCell = 0;
     p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
     p->iCell++;
-    if( z==0 ) rc = SQLITE_NOMEM;
+    if( z==0 ) rc = SQLITE_NOMEM_BKPT;
   }
 
 
@@ -165796,7 +169435,7 @@ statNextRestart:
       pCsr->nUnused = p->nUnused;
       pCsr->nMxPayload = p->nMxPayload;
       pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
-      if( z==0 ) rc = SQLITE_NOMEM;
+      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
       nPayload = 0;
       for(i=0; i<p->nCell; i++){
         nPayload += p->aCell[i].nLocal;
@@ -165822,7 +169461,7 @@ static int statFilter(
   StatTable *pTab = (StatTable*)(pCursor->pVtab);
   char *zSql;
   int rc = SQLITE_OK;
-  char *zMaster;
+  const char *zMaster;
 
   if( idxNum==1 ){
     const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
@@ -165830,7 +169469,7 @@ static int statFilter(
     if( pCsr->iDb<0 ){
       sqlite3_free(pCursor->pVtab->zErrMsg);
       pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
-      return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+      return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT;
     }
   }else{
     pCsr->iDb = pTab->iDb;
@@ -165846,7 +169485,7 @@ static int statFilter(
       "  FROM \"%w\".%s WHERE rootpage!=0"
       "  ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster);
   if( zSql==0 ){
-    return SQLITE_NOMEM;
+    return SQLITE_NOMEM_BKPT;
   }else{
     rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
     sqlite3_free(zSql);
@@ -165944,6 +169583,4648 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
 #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
 
 /************** End of dbstat.c **********************************************/
+/************** Begin file sqlite3session.c **********************************/
+
+#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+/* #include "sqlite3session.h" */
+/* #include <assert.h> */
+/* #include <string.h> */
+
+#ifndef SQLITE_AMALGAMATION
+/* # include "sqliteInt.h" */
+/* # include "vdbeInt.h" */
+#endif
+
+typedef struct SessionTable SessionTable;
+typedef struct SessionChange SessionChange;
+typedef struct SessionBuffer SessionBuffer;
+typedef struct SessionInput SessionInput;
+
+/*
+** Minimum chunk size used by streaming versions of functions.
+*/
+#ifndef SESSIONS_STRM_CHUNK_SIZE
+# ifdef SQLITE_TEST
+#   define SESSIONS_STRM_CHUNK_SIZE 64
+# else
+#   define SESSIONS_STRM_CHUNK_SIZE 1024
+# endif
+#endif
+
+typedef struct SessionHook SessionHook;
+struct SessionHook {
+  void *pCtx;
+  int (*xOld)(void*,int,sqlite3_value**);
+  int (*xNew)(void*,int,sqlite3_value**);
+  int (*xCount)(void*);
+  int (*xDepth)(void*);
+};
+
+/*
+** Session handle structure.
+*/
+struct sqlite3_session {
+  sqlite3 *db;                    /* Database handle session is attached to */
+  char *zDb;                      /* Name of database session is attached to */
+  int bEnable;                    /* True if currently recording */
+  int bIndirect;                  /* True if all changes are indirect */
+  int bAutoAttach;                /* True to auto-attach tables */
+  int rc;                         /* Non-zero if an error has occurred */
+  void *pFilterCtx;               /* First argument to pass to xTableFilter */
+  int (*xTableFilter)(void *pCtx, const char *zTab);
+  sqlite3_session *pNext;         /* Next session object on same db. */
+  SessionTable *pTable;           /* List of attached tables */
+  SessionHook hook;               /* APIs to grab new and old data with */
+};
+
+/*
+** Instances of this structure are used to build strings or binary records.
+*/
+struct SessionBuffer {
+  u8 *aBuf;                       /* Pointer to changeset buffer */
+  int nBuf;                       /* Size of buffer aBuf */
+  int nAlloc;                     /* Size of allocation containing aBuf */
+};
+
+/*
+** An object of this type is used internally as an abstraction for 
+** input data. Input data may be supplied either as a single large buffer
+** (e.g. sqlite3changeset_start()) or using a stream function (e.g.
+**  sqlite3changeset_start_strm()).
+*/
+struct SessionInput {
+  int bNoDiscard;                 /* If true, discard no data */
+  int iCurrent;                   /* Offset in aData[] of current change */
+  int iNext;                      /* Offset in aData[] of next change */
+  u8 *aData;                      /* Pointer to buffer containing changeset */
+  int nData;                      /* Number of bytes in aData */
+
+  SessionBuffer buf;              /* Current read buffer */
+  int (*xInput)(void*, void*, int*);        /* Input stream call (or NULL) */
+  void *pIn;                                /* First argument to xInput */
+  int bEof;                       /* Set to true after xInput finished */
+};
+
+/*
+** Structure for changeset iterators.
+*/
+struct sqlite3_changeset_iter {
+  SessionInput in;                /* Input buffer or stream */
+  SessionBuffer tblhdr;           /* Buffer to hold apValue/zTab/abPK/ */
+  int bPatchset;                  /* True if this is a patchset */
+  int rc;                         /* Iterator error code */
+  sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
+  char *zTab;                     /* Current table */
+  int nCol;                       /* Number of columns in zTab */
+  int op;                         /* Current operation */
+  int bIndirect;                  /* True if current change was indirect */
+  u8 *abPK;                       /* Primary key array */
+  sqlite3_value **apValue;        /* old.* and new.* values */
+};
+
+/*
+** Each session object maintains a set of the following structures, one
+** for each table the session object is monitoring. The structures are
+** stored in a linked list starting at sqlite3_session.pTable.
+**
+** The keys of the SessionTable.aChange[] hash table are all rows that have
+** been modified in any way since the session object was attached to the
+** table.
+**
+** The data associated with each hash-table entry is a structure containing
+** a subset of the initial values that the modified row contained at the
+** start of the session. Or no initial values if the row was inserted.
+*/
+struct SessionTable {
+  SessionTable *pNext;
+  char *zName;                    /* Local name of table */
+  int nCol;                       /* Number of columns in table zName */
+  const char **azCol;             /* Column names */
+  u8 *abPK;                       /* Array of primary key flags */
+  int nEntry;                     /* Total number of entries in hash table */
+  int nChange;                    /* Size of apChange[] array */
+  SessionChange **apChange;       /* Hash table buckets */
+};
+
+/* 
+** RECORD FORMAT:
+**
+** The following record format is similar to (but not compatible with) that 
+** used in SQLite database files. This format is used as part of the 
+** change-set binary format, and so must be architecture independent.
+**
+** Unlike the SQLite database record format, each field is self-contained -
+** there is no separation of header and data. Each field begins with a
+** single byte describing its type, as follows:
+**
+**       0x00: Undefined value.
+**       0x01: Integer value.
+**       0x02: Real value.
+**       0x03: Text value.
+**       0x04: Blob value.
+**       0x05: SQL NULL value.
+**
+** Note that the above match the definitions of SQLITE_INTEGER, SQLITE_TEXT
+** and so on in sqlite3.h. For undefined and NULL values, the field consists
+** only of the single type byte. For other types of values, the type byte
+** is followed by:
+**
+**   Text values:
+**     A varint containing the number of bytes in the value (encoded using
+**     UTF-8). Followed by a buffer containing the UTF-8 representation
+**     of the text value. There is no nul terminator.
+**
+**   Blob values:
+**     A varint containing the number of bytes in the value, followed by
+**     a buffer containing the value itself.
+**
+**   Integer values:
+**     An 8-byte big-endian integer value.
+**
+**   Real values:
+**     An 8-byte big-endian IEEE 754-2008 real value.
+**
+** Varint values are encoded in the same way as varints in the SQLite 
+** record format.
+**
+** CHANGESET FORMAT:
+**
+** A changeset is a collection of DELETE, UPDATE and INSERT operations on
+** one or more tables. Operations on a single table are grouped together,
+** but may occur in any order (i.e. deletes, updates and inserts are all
+** mixed together).
+**
+** Each group of changes begins with a table header:
+**
+**   1 byte: Constant 0x54 (capital 'T')
+**   Varint: Number of columns in the table.
+**   nCol bytes: 0x01 for PK columns, 0x00 otherwise.
+**   N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
+**
+** Followed by one or more changes to the table.
+**
+**   1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
+**   1 byte: The "indirect-change" flag.
+**   old.* record: (delete and update only)
+**   new.* record: (insert and update only)
+**
+** The "old.*" and "new.*" records, if present, are N field records in the
+** format described above under "RECORD FORMAT", where N is the number of
+** columns in the table. The i'th field of each record is associated with
+** the i'th column of the table, counting from left to right in the order
+** in which columns were declared in the CREATE TABLE statement.
+**
+** The new.* record that is part of each INSERT change contains the values
+** that make up the new row. Similarly, the old.* record that is part of each
+** DELETE change contains the values that made up the row that was deleted 
+** from the database. In the changeset format, the records that are part
+** of INSERT or DELETE changes never contain any undefined (type byte 0x00)
+** fields.
+**
+** Within the old.* record associated with an UPDATE change, all fields
+** associated with table columns that are not PRIMARY KEY columns and are
+** not modified by the UPDATE change are set to "undefined". Other fields
+** are set to the values that made up the row before the UPDATE that the
+** change records took place. Within the new.* record, fields associated 
+** with table columns modified by the UPDATE change contain the new 
+** values. Fields associated with table columns that are not modified
+** are set to "undefined".
+**
+** PATCHSET FORMAT:
+**
+** A patchset is also a collection of changes. It is similar to a changeset,
+** but leaves undefined those fields that are not useful if no conflict
+** resolution is required when applying the changeset.
+**
+** Each group of changes begins with a table header:
+**
+**   1 byte: Constant 0x50 (capital 'P')
+**   Varint: Number of columns in the table.
+**   nCol bytes: 0x01 for PK columns, 0x00 otherwise.
+**   N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
+**
+** Followed by one or more changes to the table.
+**
+**   1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
+**   1 byte: The "indirect-change" flag.
+**   single record: (PK fields for DELETE, PK and modified fields for UPDATE,
+**                   full record for INSERT).
+**
+** As in the changeset format, each field of the single record that is part
+** of a patchset change is associated with the correspondingly positioned
+** table column, counting from left to right within the CREATE TABLE 
+** statement.
+**
+** For a DELETE change, all fields within the record except those associated
+** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields
+** contain the values identifying the row to delete.
+**
+** For an UPDATE change, all fields except those associated with PRIMARY KEY
+** columns and columns that are modified by the UPDATE are set to "undefined".
+** PRIMARY KEY fields contain the values identifying the table row to update,
+** and fields associated with modified columns contain the new column values.
+**
+** The records associated with INSERT changes are in the same format as for
+** changesets. It is not possible for a record associated with an INSERT
+** change to contain a field set to "undefined".
+*/
+
+/*
+** For each row modified during a session, there exists a single instance of
+** this structure stored in a SessionTable.aChange[] hash table.
+*/
+struct SessionChange {
+  int op;                         /* One of UPDATE, DELETE, INSERT */
+  int bIndirect;                  /* True if this change is "indirect" */
+  int nRecord;                    /* Number of bytes in buffer aRecord[] */
+  u8 *aRecord;                    /* Buffer containing old.* record */
+  SessionChange *pNext;           /* For hash-table collisions */
+};
+
+/*
+** Write a varint with value iVal into the buffer at aBuf. Return the 
+** number of bytes written.
+*/
+static int sessionVarintPut(u8 *aBuf, int iVal){
+  return putVarint32(aBuf, iVal);
+}
+
+/*
+** Return the number of bytes required to store value iVal as a varint.
+*/
+static int sessionVarintLen(int iVal){
+  return sqlite3VarintLen(iVal);
+}
+
+/*
+** Read a varint value from aBuf[] into *piVal. Return the number of 
+** bytes read.
+*/
+static int sessionVarintGet(u8 *aBuf, int *piVal){
+  return getVarint32(aBuf, *piVal);
+}
+
+/* Load an unaligned and unsigned 32-bit integer */
+#define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
+
+/*
+** Read a 64-bit big-endian integer value from buffer aRec[]. Return
+** the value read.
+*/
+static sqlite3_int64 sessionGetI64(u8 *aRec){
+  u64 x = SESSION_UINT32(aRec);
+  u32 y = SESSION_UINT32(aRec+4);
+  x = (x<<32) + y;
+  return (sqlite3_int64)x;
+}
+
+/*
+** Write a 64-bit big-endian integer value to the buffer aBuf[].
+*/
+static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
+  aBuf[0] = (i>>56) & 0xFF;
+  aBuf[1] = (i>>48) & 0xFF;
+  aBuf[2] = (i>>40) & 0xFF;
+  aBuf[3] = (i>>32) & 0xFF;
+  aBuf[4] = (i>>24) & 0xFF;
+  aBuf[5] = (i>>16) & 0xFF;
+  aBuf[6] = (i>> 8) & 0xFF;
+  aBuf[7] = (i>> 0) & 0xFF;
+}
+
+/*
+** This function is used to serialize the contents of value pValue (see
+** comment titled "RECORD FORMAT" above).
+**
+** If it is non-NULL, the serialized form of the value is written to 
+** buffer aBuf. *pnWrite is set to the number of bytes written before
+** returning. Or, if aBuf is NULL, the only thing this function does is
+** set *pnWrite.
+**
+** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs
+** within a call to sqlite3_value_text() (may fail if the db is utf-16)) 
+** SQLITE_NOMEM is returned.
+*/
+static int sessionSerializeValue(
+  u8 *aBuf,                       /* If non-NULL, write serialized value here */
+  sqlite3_value *pValue,          /* Value to serialize */
+  int *pnWrite                    /* IN/OUT: Increment by bytes written */
+){
+  int nByte;                      /* Size of serialized value in bytes */
+
+  if( pValue ){
+    int eType;                    /* Value type (SQLITE_NULL, TEXT etc.) */
+  
+    eType = sqlite3_value_type(pValue);
+    if( aBuf ) aBuf[0] = eType;
+  
+    switch( eType ){
+      case SQLITE_NULL: 
+        nByte = 1;
+        break;
+  
+      case SQLITE_INTEGER: 
+      case SQLITE_FLOAT:
+        if( aBuf ){
+          /* TODO: SQLite does something special to deal with mixed-endian
+          ** floating point values (e.g. ARM7). This code probably should
+          ** too.  */
+          u64 i;
+          if( eType==SQLITE_INTEGER ){
+            i = (u64)sqlite3_value_int64(pValue);
+          }else{
+            double r;
+            assert( sizeof(double)==8 && sizeof(u64)==8 );
+            r = sqlite3_value_double(pValue);
+            memcpy(&i, &r, 8);
+          }
+          sessionPutI64(&aBuf[1], i);
+        }
+        nByte = 9; 
+        break;
+  
+      default: {
+        u8 *z;
+        int n;
+        int nVarint;
+  
+        assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
+        if( eType==SQLITE_TEXT ){
+          z = (u8 *)sqlite3_value_text(pValue);
+        }else{
+          z = (u8 *)sqlite3_value_blob(pValue);
+        }
+        n = sqlite3_value_bytes(pValue);
+        if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
+        nVarint = sessionVarintLen(n);
+  
+        if( aBuf ){
+          sessionVarintPut(&aBuf[1], n);
+          memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? 
+              sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n
+          );
+        }
+  
+        nByte = 1 + nVarint + n;
+        break;
+      }
+    }
+  }else{
+    nByte = 1;
+    if( aBuf ) aBuf[0] = '\0';
+  }
+
+  if( pnWrite ) *pnWrite += nByte;
+  return SQLITE_OK;
+}
+
+
+/*
+** This macro is used to calculate hash key values for data structures. In
+** order to use this macro, the entire data structure must be represented
+** as a series of unsigned integers. In order to calculate a hash-key value
+** for a data structure represented as three such integers, the macro may
+** then be used as follows:
+**
+**    int hash_key_value;
+**    hash_key_value = HASH_APPEND(0, <value 1>);
+**    hash_key_value = HASH_APPEND(hash_key_value, <value 2>);
+**    hash_key_value = HASH_APPEND(hash_key_value, <value 3>);
+**
+** In practice, the data structures this macro is used for are the primary
+** key values of modified rows.
+*/
+#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add)
+
+/*
+** Append the hash of the 64-bit integer passed as the second argument to the
+** hash-key value passed as the first. Return the new hash-key value.
+*/
+static unsigned int sessionHashAppendI64(unsigned int h, i64 i){
+  h = HASH_APPEND(h, i & 0xFFFFFFFF);
+  return HASH_APPEND(h, (i>>32)&0xFFFFFFFF);
+}
+
+/*
+** Append the hash of the blob passed via the second and third arguments to 
+** the hash-key value passed as the first. Return the new hash-key value.
+*/
+static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){
+  int i;
+  for(i=0; i<n; i++) h = HASH_APPEND(h, z[i]);
+  return h;
+}
+
+/*
+** Append the hash of the data type passed as the second argument to the
+** hash-key value passed as the first. Return the new hash-key value.
+*/
+static unsigned int sessionHashAppendType(unsigned int h, int eType){
+  return HASH_APPEND(h, eType);
+}
+
+/*
+** This function may only be called from within a pre-update callback.
+** It calculates a hash based on the primary key values of the old.* or 
+** new.* row currently available and, assuming no error occurs, writes it to
+** *piHash before returning. If the primary key contains one or more NULL
+** values, *pbNullPK is set to true before returning.
+**
+** If an error occurs, an SQLite error code is returned and the final values
+** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned
+** and the output variables are set as described above.
+*/
+static int sessionPreupdateHash(
+  sqlite3_session *pSession,      /* Session object that owns pTab */
+  SessionTable *pTab,             /* Session table handle */
+  int bNew,                       /* True to hash the new.* PK */
+  int *piHash,                    /* OUT: Hash value */
+  int *pbNullPK                   /* OUT: True if there are NULL values in PK */
+){
+  unsigned int h = 0;             /* Hash value to return */
+  int i;                          /* Used to iterate through columns */
+
+  assert( *pbNullPK==0 );
+  assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
+  for(i=0; i<pTab->nCol; i++){
+    if( pTab->abPK[i] ){
+      int rc;
+      int eType;
+      sqlite3_value *pVal;
+
+      if( bNew ){
+        rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
+      }else{
+        rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
+      }
+      if( rc!=SQLITE_OK ) return rc;
+
+      eType = sqlite3_value_type(pVal);
+      h = sessionHashAppendType(h, eType);
+      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+        i64 iVal;
+        if( eType==SQLITE_INTEGER ){
+          iVal = sqlite3_value_int64(pVal);
+        }else{
+          double rVal = sqlite3_value_double(pVal);
+          assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
+          memcpy(&iVal, &rVal, 8);
+        }
+        h = sessionHashAppendI64(h, iVal);
+      }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+        const u8 *z;
+        int n;
+        if( eType==SQLITE_TEXT ){
+          z = (const u8 *)sqlite3_value_text(pVal);
+        }else{
+          z = (const u8 *)sqlite3_value_blob(pVal);
+        }
+        n = sqlite3_value_bytes(pVal);
+        if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
+        h = sessionHashAppendBlob(h, n, z);
+      }else{
+        assert( eType==SQLITE_NULL );
+        *pbNullPK = 1;
+      }
+    }
+  }
+
+  *piHash = (h % pTab->nChange);
+  return SQLITE_OK;
+}
+
+/*
+** The buffer that the argument points to contains a serialized SQL value.
+** Return the number of bytes of space occupied by the value (including
+** the type byte).
+*/
+static int sessionSerialLen(u8 *a){
+  int e = *a;
+  int n;
+  if( e==0 ) return 1;
+  if( e==SQLITE_NULL ) return 1;
+  if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
+  return sessionVarintGet(&a[1], &n) + 1 + n;
+}
+
+/*
+** Based on the primary key values stored in change aRecord, calculate a
+** hash key. Assume the has table has nBucket buckets. The hash keys
+** calculated by this function are compatible with those calculated by
+** sessionPreupdateHash().
+**
+** The bPkOnly argument is non-zero if the record at aRecord[] is from
+** a patchset DELETE. In this case the non-PK fields are omitted entirely.
+*/
+static unsigned int sessionChangeHash(
+  SessionTable *pTab,             /* Table handle */
+  int bPkOnly,                    /* Record consists of PK fields only */
+  u8 *aRecord,                    /* Change record */
+  int nBucket                     /* Assume this many buckets in hash table */
+){
+  unsigned int h = 0;             /* Value to return */
+  int i;                          /* Used to iterate through columns */
+  u8 *a = aRecord;                /* Used to iterate through change record */
+
+  for(i=0; i<pTab->nCol; i++){
+    int eType = *a;
+    int isPK = pTab->abPK[i];
+    if( bPkOnly && isPK==0 ) continue;
+
+    /* It is not possible for eType to be SQLITE_NULL here. The session 
+    ** module does not record changes for rows with NULL values stored in
+    ** primary key columns. */
+    assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT 
+         || eType==SQLITE_TEXT || eType==SQLITE_BLOB 
+         || eType==SQLITE_NULL || eType==0 
+    );
+    assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) );
+
+    if( isPK ){
+      a++;
+      h = sessionHashAppendType(h, eType);
+      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+        h = sessionHashAppendI64(h, sessionGetI64(a));
+        a += 8;
+      }else{
+        int n; 
+        a += sessionVarintGet(a, &n);
+        h = sessionHashAppendBlob(h, n, a);
+        a += n;
+      }
+    }else{
+      a += sessionSerialLen(a);
+    }
+  }
+  return (h % nBucket);
+}
+
+/*
+** Arguments aLeft and aRight are pointers to change records for table pTab.
+** This function returns true if the two records apply to the same row (i.e.
+** have the same values stored in the primary key columns), or false 
+** otherwise.
+*/
+static int sessionChangeEqual(
+  SessionTable *pTab,             /* Table used for PK definition */
+  int bLeftPkOnly,                /* True if aLeft[] contains PK fields only */
+  u8 *aLeft,                      /* Change record */
+  int bRightPkOnly,               /* True if aRight[] contains PK fields only */
+  u8 *aRight                      /* Change record */
+){
+  u8 *a1 = aLeft;                 /* Cursor to iterate through aLeft */
+  u8 *a2 = aRight;                /* Cursor to iterate through aRight */
+  int iCol;                       /* Used to iterate through table columns */
+
+  for(iCol=0; iCol<pTab->nCol; iCol++){
+    if( pTab->abPK[iCol] ){
+      int n1 = sessionSerialLen(a1);
+      int n2 = sessionSerialLen(a2);
+
+      if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
+        return 0;
+      }
+      a1 += n1;
+      a2 += n2;
+    }else{
+      if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
+      if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
+    }
+  }
+
+  return 1;
+}
+
+/*
+** Arguments aLeft and aRight both point to buffers containing change
+** records with nCol columns. This function "merges" the two records into
+** a single records which is written to the buffer at *paOut. *paOut is
+** then set to point to one byte after the last byte written before 
+** returning.
+**
+** The merging of records is done as follows: For each column, if the 
+** aRight record contains a value for the column, copy the value from
+** their. Otherwise, if aLeft contains a value, copy it. If neither
+** record contains a value for a given column, then neither does the
+** output record.
+*/
+static void sessionMergeRecord(
+  u8 **paOut, 
+  int nCol,
+  u8 *aLeft,
+  u8 *aRight
+){
+  u8 *a1 = aLeft;                 /* Cursor used to iterate through aLeft */
+  u8 *a2 = aRight;                /* Cursor used to iterate through aRight */
+  u8 *aOut = *paOut;              /* Output cursor */
+  int iCol;                       /* Used to iterate from 0 to nCol */
+
+  for(iCol=0; iCol<nCol; iCol++){
+    int n1 = sessionSerialLen(a1);
+    int n2 = sessionSerialLen(a2);
+    if( *a2 ){
+      memcpy(aOut, a2, n2);
+      aOut += n2;
+    }else{
+      memcpy(aOut, a1, n1);
+      aOut += n1;
+    }
+    a1 += n1;
+    a2 += n2;
+  }
+
+  *paOut = aOut;
+}
+
+/*
+** This is a helper function used by sessionMergeUpdate().
+**
+** When this function is called, both *paOne and *paTwo point to a value 
+** within a change record. Before it returns, both have been advanced so 
+** as to point to the next value in the record.
+**
+** If, when this function is called, *paTwo points to a valid value (i.e.
+** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paTwo
+** pointer is returned and *pnVal is set to the number of bytes in the 
+** serialized value. Otherwise, a copy of *paOne is returned and *pnVal
+** set to the number of bytes in the value at *paOne. If *paOne points
+** to the "no value" placeholder, *pnVal is set to 1. In other words:
+**
+**   if( *paTwo is valid ) return *paTwo;
+**   return *paOne;
+**
+*/
+static u8 *sessionMergeValue(
+  u8 **paOne,                     /* IN/OUT: Left-hand buffer pointer */
+  u8 **paTwo,                     /* IN/OUT: Right-hand buffer pointer */
+  int *pnVal                      /* OUT: Bytes in returned value */
+){
+  u8 *a1 = *paOne;
+  u8 *a2 = *paTwo;
+  u8 *pRet = 0;
+  int n1;
+
+  assert( a1 );
+  if( a2 ){
+    int n2 = sessionSerialLen(a2);
+    if( *a2 ){
+      *pnVal = n2;
+      pRet = a2;
+    }
+    *paTwo = &a2[n2];
+  }
+
+  n1 = sessionSerialLen(a1);
+  if( pRet==0 ){
+    *pnVal = n1;
+    pRet = a1;
+  }
+  *paOne = &a1[n1];
+
+  return pRet;
+}
+
+/*
+** This function is used by changeset_concat() to merge two UPDATE changes
+** on the same row.
+*/
+static int sessionMergeUpdate(
+  u8 **paOut,                     /* IN/OUT: Pointer to output buffer */
+  SessionTable *pTab,             /* Table change pertains to */
+  int bPatchset,                  /* True if records are patchset records */
+  u8 *aOldRecord1,                /* old.* record for first change */
+  u8 *aOldRecord2,                /* old.* record for second change */
+  u8 *aNewRecord1,                /* new.* record for first change */
+  u8 *aNewRecord2                 /* new.* record for second change */
+){
+  u8 *aOld1 = aOldRecord1;
+  u8 *aOld2 = aOldRecord2;
+  u8 *aNew1 = aNewRecord1;
+  u8 *aNew2 = aNewRecord2;
+
+  u8 *aOut = *paOut;
+  int i;
+
+  if( bPatchset==0 ){
+    int bRequired = 0;
+
+    assert( aOldRecord1 && aNewRecord1 );
+
+    /* Write the old.* vector first. */
+    for(i=0; i<pTab->nCol; i++){
+      int nOld;
+      u8 *aOld;
+      int nNew;
+      u8 *aNew;
+
+      aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
+      aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
+      if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){
+        if( pTab->abPK[i]==0 ) bRequired = 1;
+        memcpy(aOut, aOld, nOld);
+        aOut += nOld;
+      }else{
+        *(aOut++) = '\0';
+      }
+    }
+
+    if( !bRequired ) return 0;
+  }
+
+  /* Write the new.* vector */
+  aOld1 = aOldRecord1;
+  aOld2 = aOldRecord2;
+  aNew1 = aNewRecord1;
+  aNew2 = aNewRecord2;
+  for(i=0; i<pTab->nCol; i++){
+    int nOld;
+    u8 *aOld;
+    int nNew;
+    u8 *aNew;
+
+    aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
+    aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
+    if( bPatchset==0 
+     && (pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew))) 
+    ){
+      *(aOut++) = '\0';
+    }else{
+      memcpy(aOut, aNew, nNew);
+      aOut += nNew;
+    }
+  }
+
+  *paOut = aOut;
+  return 1;
+}
+
+/*
+** This function is only called from within a pre-update-hook callback.
+** It determines if the current pre-update-hook change affects the same row
+** as the change stored in argument pChange. If so, it returns true. Otherwise
+** if the pre-update-hook does not affect the same row as pChange, it returns
+** false.
+*/
+static int sessionPreupdateEqual(
+  sqlite3_session *pSession,      /* Session object that owns SessionTable */
+  SessionTable *pTab,             /* Table associated with change */
+  SessionChange *pChange,         /* Change to compare to */
+  int op                          /* Current pre-update operation */
+){
+  int iCol;                       /* Used to iterate through columns */
+  u8 *a = pChange->aRecord;       /* Cursor used to scan change record */
+
+  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
+  for(iCol=0; iCol<pTab->nCol; iCol++){
+    if( !pTab->abPK[iCol] ){
+      a += sessionSerialLen(a);
+    }else{
+      sqlite3_value *pVal;        /* Value returned by preupdate_new/old */
+      int eType = *a++;           /* Type of value from change record */
+
+      /* The following calls to preupdate_new() and preupdate_old() can not
+      ** fail. This is because they cache their return values, and by the
+      ** time control flows to here they have already been called once from
+      ** within sessionPreupdateHash(). The first two asserts below verify
+      ** this (that the method has already been called). */
+      if( op==SQLITE_INSERT ){
+        /* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
+        pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal);
+      }else{
+        /* assert( db->pPreUpdate->pUnpacked ); */
+        pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
+      }
+      if( sqlite3_value_type(pVal)!=eType ) return 0;
+
+      /* A SessionChange object never has a NULL value in a PK column */
+      assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
+           || eType==SQLITE_BLOB    || eType==SQLITE_TEXT
+      );
+
+      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+        i64 iVal = sessionGetI64(a);
+        a += 8;
+        if( eType==SQLITE_INTEGER ){
+          if( sqlite3_value_int64(pVal)!=iVal ) return 0;
+        }else{
+          double rVal;
+          assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
+          memcpy(&rVal, &iVal, 8);
+          if( sqlite3_value_double(pVal)!=rVal ) return 0;
+        }
+      }else{
+        int n;
+        const u8 *z;
+        a += sessionVarintGet(a, &n);
+        if( sqlite3_value_bytes(pVal)!=n ) return 0;
+        if( eType==SQLITE_TEXT ){
+          z = sqlite3_value_text(pVal);
+        }else{
+          z = sqlite3_value_blob(pVal);
+        }
+        if( memcmp(a, z, n) ) return 0;
+        a += n;
+        break;
+      }
+    }
+  }
+
+  return 1;
+}
+
+/*
+** If required, grow the hash table used to store changes on table pTab 
+** (part of the session pSession). If a fatal OOM error occurs, set the
+** session object to failed and return SQLITE_ERROR. Otherwise, return
+** SQLITE_OK.
+**
+** It is possible that a non-fatal OOM error occurs in this function. In
+** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
+** Growing the hash table in this case is a performance optimization only,
+** it is not required for correct operation.
+*/
+static int sessionGrowHash(int bPatchset, SessionTable *pTab){
+  if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
+    int i;
+    SessionChange **apNew;
+    int nNew = (pTab->nChange ? pTab->nChange : 128) * 2;
+
+    apNew = (SessionChange **)sqlite3_malloc(sizeof(SessionChange *) * nNew);
+    if( apNew==0 ){
+      if( pTab->nChange==0 ){
+        return SQLITE_ERROR;
+      }
+      return SQLITE_OK;
+    }
+    memset(apNew, 0, sizeof(SessionChange *) * nNew);
+
+    for(i=0; i<pTab->nChange; i++){
+      SessionChange *p;
+      SessionChange *pNext;
+      for(p=pTab->apChange[i]; p; p=pNext){
+        int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
+        int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
+        pNext = p->pNext;
+        p->pNext = apNew[iHash];
+        apNew[iHash] = p;
+      }
+    }
+
+    sqlite3_free(pTab->apChange);
+    pTab->nChange = nNew;
+    pTab->apChange = apNew;
+  }
+
+  return SQLITE_OK;
+}
+
+/*
+** This function queries the database for the names of the columns of table
+** zThis, in schema zDb. It is expected that the table has nCol columns. If
+** not, SQLITE_SCHEMA is returned and none of the output variables are
+** populated.
+**
+** Otherwise, if they are not NULL, variable *pnCol is set to the number
+** of columns in the database table and variable *pzTab is set to point to a
+** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
+** point to an array of pointers to column names. And *pabPK (again, if not
+** NULL) is set to point to an array of booleans - true if the corresponding
+** column is part of the primary key.
+**
+** For example, if the table is declared as:
+**
+**     CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z));
+**
+** Then the four output variables are populated as follows:
+**
+**     *pnCol  = 4
+**     *pzTab  = "tbl1"
+**     *pazCol = {"w", "x", "y", "z"}
+**     *pabPK  = {1, 0, 0, 1}
+**
+** All returned buffers are part of the same single allocation, which must
+** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then
+** pointer *pazCol should be freed to release all memory. Otherwise, pointer
+** *pabPK. It is illegal for both pazCol and pabPK to be NULL.
+*/
+static int sessionTableInfo(
+  sqlite3 *db,                    /* Database connection */
+  const char *zDb,                /* Name of attached database (e.g. "main") */
+  const char *zThis,              /* Table name */
+  int *pnCol,                     /* OUT: number of columns */
+  const char **pzTab,             /* OUT: Copy of zThis */
+  const char ***pazCol,           /* OUT: Array of column names for table */
+  u8 **pabPK                      /* OUT: Array of booleans - true for PK col */
+){
+  char *zPragma;
+  sqlite3_stmt *pStmt;
+  int rc;
+  int nByte;
+  int nDbCol = 0;
+  int nThis;
+  int i;
+  u8 *pAlloc = 0;
+  char **azCol = 0;
+  u8 *abPK = 0;
+
+  assert( pazCol && pabPK );
+
+  nThis = sqlite3Strlen30(zThis);
+  zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
+  if( !zPragma ) return SQLITE_NOMEM;
+
+  rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
+  sqlite3_free(zPragma);
+  if( rc!=SQLITE_OK ) return rc;
+
+  nByte = nThis + 1;
+  while( SQLITE_ROW==sqlite3_step(pStmt) ){
+    nByte += sqlite3_column_bytes(pStmt, 1);
+    nDbCol++;
+  }
+  rc = sqlite3_reset(pStmt);
+
+  if( rc==SQLITE_OK ){
+    nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
+    pAlloc = sqlite3_malloc(nByte);
+    if( pAlloc==0 ){
+      rc = SQLITE_NOMEM;
+    }
+  }
+  if( rc==SQLITE_OK ){
+    azCol = (char **)pAlloc;
+    pAlloc = (u8 *)&azCol[nDbCol];
+    abPK = (u8 *)pAlloc;
+    pAlloc = &abPK[nDbCol];
+    if( pzTab ){
+      memcpy(pAlloc, zThis, nThis+1);
+      *pzTab = (char *)pAlloc;
+      pAlloc += nThis+1;
+    }
+  
+    i = 0;
+    while( SQLITE_ROW==sqlite3_step(pStmt) ){
+      int nName = sqlite3_column_bytes(pStmt, 1);
+      const unsigned char *zName = sqlite3_column_text(pStmt, 1);
+      if( zName==0 ) break;
+      memcpy(pAlloc, zName, nName+1);
+      azCol[i] = (char *)pAlloc;
+      pAlloc += nName+1;
+      abPK[i] = sqlite3_column_int(pStmt, 5);
+      i++;
+    }
+    rc = sqlite3_reset(pStmt);
+  
+  }
+
+  /* If successful, populate the output variables. Otherwise, zero them and
+  ** free any allocation made. An error code will be returned in this case.
+  */
+  if( rc==SQLITE_OK ){
+    *pazCol = (const char **)azCol;
+    *pabPK = abPK;
+    *pnCol = nDbCol;
+  }else{
+    *pazCol = 0;
+    *pabPK = 0;
+    *pnCol = 0;
+    if( pzTab ) *pzTab = 0;
+    sqlite3_free(azCol);
+  }
+  sqlite3_finalize(pStmt);
+  return rc;
+}
+
+/*
+** This function is only called from within a pre-update handler for a
+** write to table pTab, part of session pSession. If this is the first
+** write to this table, initalize the SessionTable.nCol, azCol[] and
+** abPK[] arrays accordingly.
+**
+** If an error occurs, an error code is stored in sqlite3_session.rc and
+** non-zero returned. Or, if no error occurs but the table has no primary
+** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
+** indicate that updates on this table should be ignored. SessionTable.abPK 
+** is set to NULL in this case.
+*/
+static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
+  if( pTab->nCol==0 ){
+    u8 *abPK;
+    assert( pTab->azCol==0 || pTab->abPK==0 );
+    pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, 
+        pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
+    );
+    if( pSession->rc==SQLITE_OK ){
+      int i;
+      for(i=0; i<pTab->nCol; i++){
+        if( abPK[i] ){
+          pTab->abPK = abPK;
+          break;
+        }
+      }
+    }
+  }
+  return (pSession->rc || pTab->abPK==0);
+}
+
+/*
+** This function is only called from with a pre-update-hook reporting a 
+** change on table pTab (attached to session pSession). The type of change
+** (UPDATE, INSERT, DELETE) is specified by the first argument.
+**
+** Unless one is already present or an error occurs, an entry is added
+** to the changed-rows hash table associated with table pTab.
+*/
+static void sessionPreupdateOneChange(
+  int op,                         /* One of SQLITE_UPDATE, INSERT, DELETE */
+  sqlite3_session *pSession,      /* Session object pTab is attached to */
+  SessionTable *pTab              /* Table that change applies to */
+){
+  int iHash; 
+  int bNull = 0; 
+  int rc = SQLITE_OK;
+
+  if( pSession->rc ) return;
+
+  /* Load table details if required */
+  if( sessionInitTable(pSession, pTab) ) return;
+
+  /* Check the number of columns in this xPreUpdate call matches the 
+  ** number of columns in the table.  */
+  if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
+    pSession->rc = SQLITE_SCHEMA;
+    return;
+  }
+
+  /* Grow the hash table if required */
+  if( sessionGrowHash(0, pTab) ){
+    pSession->rc = SQLITE_NOMEM;
+    return;
+  }
+
+  /* Calculate the hash-key for this change. If the primary key of the row
+  ** includes a NULL value, exit early. Such changes are ignored by the
+  ** session module. */
+  rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull);
+  if( rc!=SQLITE_OK ) goto error_out;
+
+  if( bNull==0 ){
+    /* Search the hash table for an existing record for this row. */
+    SessionChange *pC;
+    for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
+      if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break;
+    }
+
+    if( pC==0 ){
+      /* Create a new change object containing all the old values (if
+      ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
+      ** values (if this is an INSERT). */
+      SessionChange *pChange; /* New change object */
+      int nByte;              /* Number of bytes to allocate */
+      int i;                  /* Used to iterate through columns */
+  
+      assert( rc==SQLITE_OK );
+      pTab->nEntry++;
+  
+      /* Figure out how large an allocation is required */
+      nByte = sizeof(SessionChange);
+      for(i=0; i<pTab->nCol; i++){
+        sqlite3_value *p = 0;
+        if( op!=SQLITE_INSERT ){
+          TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
+          assert( trc==SQLITE_OK );
+        }else if( pTab->abPK[i] ){
+          TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
+          assert( trc==SQLITE_OK );
+        }
+
+        /* This may fail if SQLite value p contains a utf-16 string that must
+        ** be converted to utf-8 and an OOM error occurs while doing so. */
+        rc = sessionSerializeValue(0, p, &nByte);
+        if( rc!=SQLITE_OK ) goto error_out;
+      }
+  
+      /* Allocate the change object */
+      pChange = (SessionChange *)sqlite3_malloc(nByte);
+      if( !pChange ){
+        rc = SQLITE_NOMEM;
+        goto error_out;
+      }else{
+        memset(pChange, 0, sizeof(SessionChange));
+        pChange->aRecord = (u8 *)&pChange[1];
+      }
+  
+      /* Populate the change object. None of the preupdate_old(),
+      ** preupdate_new() or SerializeValue() calls below may fail as all
+      ** required values and encodings have already been cached in memory.
+      ** It is not possible for an OOM to occur in this block. */
+      nByte = 0;
+      for(i=0; i<pTab->nCol; i++){
+        sqlite3_value *p = 0;
+        if( op!=SQLITE_INSERT ){
+          pSession->hook.xOld(pSession->hook.pCtx, i, &p);
+        }else if( pTab->abPK[i] ){
+          pSession->hook.xNew(pSession->hook.pCtx, i, &p);
+        }
+        sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte);
+      }
+
+      /* Add the change to the hash-table */
+      if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
+        pChange->bIndirect = 1;
+      }
+      pChange->nRecord = nByte;
+      pChange->op = op;
+      pChange->pNext = pTab->apChange[iHash];
+      pTab->apChange[iHash] = pChange;
+
+    }else if( pC->bIndirect ){
+      /* If the existing change is considered "indirect", but this current
+      ** change is "direct", mark the change object as direct. */
+      if( pSession->hook.xDepth(pSession->hook.pCtx)==0 
+       && pSession->bIndirect==0 
+      ){
+        pC->bIndirect = 0;
+      }
+    }
+  }
+
+  /* If an error has occurred, mark the session object as failed. */
+ error_out:
+  if( rc!=SQLITE_OK ){
+    pSession->rc = rc;
+  }
+}
+
+static int sessionFindTable(
+  sqlite3_session *pSession, 
+  const char *zName,
+  SessionTable **ppTab
+){
+  int rc = SQLITE_OK;
+  int nName = sqlite3Strlen30(zName);
+  SessionTable *pRet;
+
+  /* Search for an existing table */
+  for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){
+    if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break;
+  }
+
+  if( pRet==0 && pSession->bAutoAttach ){
+    /* If there is a table-filter configured, invoke it. If it returns 0,
+    ** do not automatically add the new table. */
+    if( pSession->xTableFilter==0
+     || pSession->xTableFilter(pSession->pFilterCtx, zName) 
+    ){
+      rc = sqlite3session_attach(pSession, zName);
+      if( rc==SQLITE_OK ){
+        for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext);
+        assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
+      }
+    }
+  }
+
+  assert( rc==SQLITE_OK || pRet==0 );
+  *ppTab = pRet;
+  return rc;
+}
+
+/*
+** The 'pre-update' hook registered by this module with SQLite databases.
+*/
+static void xPreUpdate(
+  void *pCtx,                     /* Copy of third arg to preupdate_hook() */
+  sqlite3 *db,                    /* Database handle */
+  int op,                         /* SQLITE_UPDATE, DELETE or INSERT */
+  char const *zDb,                /* Database name */
+  char const *zName,              /* Table name */
+  sqlite3_int64 iKey1,            /* Rowid of row about to be deleted/updated */
+  sqlite3_int64 iKey2             /* New rowid value (for a rowid UPDATE) */
+){
+  sqlite3_session *pSession;
+  int nDb = sqlite3Strlen30(zDb);
+
+  assert( sqlite3_mutex_held(db->mutex) );
+
+  for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
+    SessionTable *pTab;
+
+    /* If this session is attached to a different database ("main", "temp" 
+    ** etc.), or if it is not currently enabled, there is nothing to do. Skip 
+    ** to the next session object attached to this database. */
+    if( pSession->bEnable==0 ) continue;
+    if( pSession->rc ) continue;
+    if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
+
+    pSession->rc = sessionFindTable(pSession, zName, &pTab);
+    if( pTab ){
+      assert( pSession->rc==SQLITE_OK );
+      sessionPreupdateOneChange(op, pSession, pTab);
+      if( op==SQLITE_UPDATE ){
+        sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab);
+      }
+    }
+  }
+}
+
+/*
+** The pre-update hook implementations.
+*/
+static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){
+  return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal);
+}
+static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){
+  return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal);
+}
+static int sessionPreupdateCount(void *pCtx){
+  return sqlite3_preupdate_count((sqlite3*)pCtx);
+}
+static int sessionPreupdateDepth(void *pCtx){
+  return sqlite3_preupdate_depth((sqlite3*)pCtx);
+}
+
+/*
+** Install the pre-update hooks on the session object passed as the only
+** argument.
+*/
+static void sessionPreupdateHooks(
+  sqlite3_session *pSession
+){
+  pSession->hook.pCtx = (void*)pSession->db;
+  pSession->hook.xOld = sessionPreupdateOld;
+  pSession->hook.xNew = sessionPreupdateNew;
+  pSession->hook.xCount = sessionPreupdateCount;
+  pSession->hook.xDepth = sessionPreupdateDepth;
+}
+
+typedef struct SessionDiffCtx SessionDiffCtx;
+struct SessionDiffCtx {
+  sqlite3_stmt *pStmt;
+  int nOldOff;
+};
+
+/*
+** The diff hook implementations.
+*/
+static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){
+  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
+  *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff);
+  return SQLITE_OK;
+}
+static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){
+  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
+  *ppVal = sqlite3_column_value(p->pStmt, iVal);
+   return SQLITE_OK;
+}
+static int sessionDiffCount(void *pCtx){
+  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
+  return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt);
+}
+static int sessionDiffDepth(void *pCtx){
+  return 0;
+}
+
+/*
+** Install the diff hooks on the session object passed as the only
+** argument.
+*/
+static void sessionDiffHooks(
+  sqlite3_session *pSession,
+  SessionDiffCtx *pDiffCtx
+){
+  pSession->hook.pCtx = (void*)pDiffCtx;
+  pSession->hook.xOld = sessionDiffOld;
+  pSession->hook.xNew = sessionDiffNew;
+  pSession->hook.xCount = sessionDiffCount;
+  pSession->hook.xDepth = sessionDiffDepth;
+}
+
+static char *sessionExprComparePK(
+  int nCol,
+  const char *zDb1, const char *zDb2, 
+  const char *zTab,
+  const char **azCol, u8 *abPK
+){
+  int i;
+  const char *zSep = "";
+  char *zRet = 0;
+
+  for(i=0; i<nCol; i++){
+    if( abPK[i] ){
+      zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"=\"%w\".\"%w\".\"%w\"",
+          zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
+      );
+      zSep = " AND ";
+      if( zRet==0 ) break;
+    }
+  }
+
+  return zRet;
+}
+
+static char *sessionExprCompareOther(
+  int nCol,
+  const char *zDb1, const char *zDb2, 
+  const char *zTab,
+  const char **azCol, u8 *abPK
+){
+  int i;
+  const char *zSep = "";
+  char *zRet = 0;
+  int bHave = 0;
+
+  for(i=0; i<nCol; i++){
+    if( abPK[i]==0 ){
+      bHave = 1;
+      zRet = sqlite3_mprintf(
+          "%z%s\"%w\".\"%w\".\"%w\" IS NOT \"%w\".\"%w\".\"%w\"",
+          zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
+      );
+      zSep = " OR ";
+      if( zRet==0 ) break;
+    }
+  }
+
+  if( bHave==0 ){
+    assert( zRet==0 );
+    zRet = sqlite3_mprintf("0");
+  }
+
+  return zRet;
+}
+
+static char *sessionSelectFindNew(
+  int nCol,
+  const char *zDb1,      /* Pick rows in this db only */
+  const char *zDb2,      /* But not in this one */
+  const char *zTbl,      /* Table name */
+  const char *zExpr
+){
+  char *zRet = sqlite3_mprintf(
+      "SELECT * FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
+      "  SELECT 1 FROM \"%w\".\"%w\" WHERE %s"
+      ")",
+      zDb1, zTbl, zDb2, zTbl, zExpr
+  );
+  return zRet;
+}
+
+static int sessionDiffFindNew(
+  int op,
+  sqlite3_session *pSession,
+  SessionTable *pTab,
+  const char *zDb1,
+  const char *zDb2,
+  char *zExpr
+){
+  int rc = SQLITE_OK;
+  char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr);
+
+  if( zStmt==0 ){
+    rc = SQLITE_NOMEM;
+  }else{
+    sqlite3_stmt *pStmt;
+    rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
+    if( rc==SQLITE_OK ){
+      SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
+      pDiffCtx->pStmt = pStmt;
+      pDiffCtx->nOldOff = 0;
+      while( SQLITE_ROW==sqlite3_step(pStmt) ){
+        sessionPreupdateOneChange(op, pSession, pTab);
+      }
+      rc = sqlite3_finalize(pStmt);
+    }
+    sqlite3_free(zStmt);
+  }
+
+  return rc;
+}
+
+static int sessionDiffFindModified(
+  sqlite3_session *pSession, 
+  SessionTable *pTab, 
+  const char *zFrom, 
+  const char *zExpr
+){
+  int rc = SQLITE_OK;
+
+  char *zExpr2 = sessionExprCompareOther(pTab->nCol,
+      pSession->zDb, zFrom, pTab->zName, pTab->azCol, pTab->abPK
+  );
+  if( zExpr2==0 ){
+    rc = SQLITE_NOMEM;
+  }else{
+    char *zStmt = sqlite3_mprintf(
+        "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
+        pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
+    );
+    if( zStmt==0 ){
+      rc = SQLITE_NOMEM;
+    }else{
+      sqlite3_stmt *pStmt;
+      rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
+
+      if( rc==SQLITE_OK ){
+        SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
+        pDiffCtx->pStmt = pStmt;
+        pDiffCtx->nOldOff = pTab->nCol;
+        while( SQLITE_ROW==sqlite3_step(pStmt) ){
+          sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab);
+        }
+        rc = sqlite3_finalize(pStmt);
+      }
+      sqlite3_free(zStmt);
+    }
+  }
+
+  return rc;
+}
+
+SQLITE_API int SQLITE_STDCALL sqlite3session_diff(
+  sqlite3_session *pSession,
+  const char *zFrom,
+  const char *zTbl,
+  char **pzErrMsg
+){
+  const char *zDb = pSession->zDb;
+  int rc = pSession->rc;
+  SessionDiffCtx d;
+
+  memset(&d, 0, sizeof(d));
+  sessionDiffHooks(pSession, &d);
+
+  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+  if( pzErrMsg ) *pzErrMsg = 0;
+  if( rc==SQLITE_OK ){
+    char *zExpr = 0;
+    sqlite3 *db = pSession->db;
+    SessionTable *pTo;            /* Table zTbl */
+
+    /* Locate and if necessary initialize the target table object */
+    rc = sessionFindTable(pSession, zTbl, &pTo);
+    if( pTo==0 ) goto diff_out;
+    if( sessionInitTable(pSession, pTo) ){
+      rc = pSession->rc;
+      goto diff_out;
+    }
+
+    /* Check the table schemas match */
+    if( rc==SQLITE_OK ){
+      int bHasPk = 0;
+      int bMismatch = 0;
+      int nCol;                   /* Columns in zFrom.zTbl */
+      u8 *abPK;
+      const char **azCol = 0;
+      rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK);
+      if( rc==SQLITE_OK ){
+        if( pTo->nCol!=nCol ){
+          bMismatch = 1;
+        }else{
+          int i;
+          for(i=0; i<nCol; i++){
+            if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
+            if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
+            if( abPK[i] ) bHasPk = 1;
+          }
+        }
+
+      }
+      sqlite3_free((char*)azCol);
+      if( bMismatch ){
+        *pzErrMsg = sqlite3_mprintf("table schemas do not match");
+        rc = SQLITE_SCHEMA;
+      }
+      if( bHasPk==0 ){
+        /* Ignore tables with no primary keys */
+        goto diff_out;
+      }
+    }
+
+    if( rc==SQLITE_OK ){
+      zExpr = sessionExprComparePK(pTo->nCol, 
+          zDb, zFrom, pTo->zName, pTo->azCol, pTo->abPK
+      );
+    }
+
+    /* Find new rows */
+    if( rc==SQLITE_OK ){
+      rc = sessionDiffFindNew(SQLITE_INSERT, pSession, pTo, zDb, zFrom, zExpr);
+    }
+
+    /* Find old rows */
+    if( rc==SQLITE_OK ){
+      rc = sessionDiffFindNew(SQLITE_DELETE, pSession, pTo, zFrom, zDb, zExpr);
+    }
+
+    /* Find modified rows */
+    if( rc==SQLITE_OK ){
+      rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr);
+    }
+
+    sqlite3_free(zExpr);
+  }
+
+ diff_out:
+  sessionPreupdateHooks(pSession);
+  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+  return rc;
+}
+
+/*
+** Create a session object. This session object will record changes to
+** database zDb attached to connection db.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_create(
+  sqlite3 *db,                    /* Database handle */
+  const char *zDb,                /* Name of db (e.g. "main") */
+  sqlite3_session **ppSession     /* OUT: New session object */
+){
+  sqlite3_session *pNew;          /* Newly allocated session object */
+  sqlite3_session *pOld;          /* Session object already attached to db */
+  int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */
+
+  /* Zero the output value in case an error occurs. */
+  *ppSession = 0;
+
+  /* Allocate and populate the new session object. */
+  pNew = (sqlite3_session *)sqlite3_malloc(sizeof(sqlite3_session) + nDb + 1);
+  if( !pNew ) return SQLITE_NOMEM;
+  memset(pNew, 0, sizeof(sqlite3_session));
+  pNew->db = db;
+  pNew->zDb = (char *)&pNew[1];
+  pNew->bEnable = 1;
+  memcpy(pNew->zDb, zDb, nDb+1);
+  sessionPreupdateHooks(pNew);
+
+  /* Add the new session object to the linked list of session objects 
+  ** attached to database handle $db. Do this under the cover of the db
+  ** handle mutex.  */
+  sqlite3_mutex_enter(sqlite3_db_mutex(db));
+  pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew);
+  pNew->pNext = pOld;
+  sqlite3_mutex_leave(sqlite3_db_mutex(db));
+
+  *ppSession = pNew;
+  return SQLITE_OK;
+}
+
+/*
+** Free the list of table objects passed as the first argument. The contents
+** of the changed-rows hash tables are also deleted.
+*/
+static void sessionDeleteTable(SessionTable *pList){
+  SessionTable *pNext;
+  SessionTable *pTab;
+
+  for(pTab=pList; pTab; pTab=pNext){
+    int i;
+    pNext = pTab->pNext;
+    for(i=0; i<pTab->nChange; i++){
+      SessionChange *p;
+      SessionChange *pNextChange;
+      for(p=pTab->apChange[i]; p; p=pNextChange){
+        pNextChange = p->pNext;
+        sqlite3_free(p);
+      }
+    }
+    sqlite3_free((char*)pTab->azCol);  /* cast works around VC++ bug */
+    sqlite3_free(pTab->apChange);
+    sqlite3_free(pTab);
+  }
+}
+
+/*
+** Delete a session object previously allocated using sqlite3session_create().
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3session_delete(sqlite3_session *pSession){
+  sqlite3 *db = pSession->db;
+  sqlite3_session *pHead;
+  sqlite3_session **pp;
+
+  /* Unlink the session from the linked list of sessions attached to the
+  ** database handle. Hold the db mutex while doing so.  */
+  sqlite3_mutex_enter(sqlite3_db_mutex(db));
+  pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0);
+  for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){
+    if( (*pp)==pSession ){
+      *pp = (*pp)->pNext;
+      if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead);
+      break;
+    }
+  }
+  sqlite3_mutex_leave(sqlite3_db_mutex(db));
+
+  /* Delete all attached table objects. And the contents of their 
+  ** associated hash-tables. */
+  sessionDeleteTable(pSession->pTable);
+
+  /* Free the session object itself. */
+  sqlite3_free(pSession);
+}
+
+/*
+** Set a table filter on a Session Object.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3session_table_filter(
+  sqlite3_session *pSession, 
+  int(*xFilter)(void*, const char*),
+  void *pCtx                      /* First argument passed to xFilter */
+){
+  pSession->bAutoAttach = 1;
+  pSession->pFilterCtx = pCtx;
+  pSession->xTableFilter = xFilter;
+}
+
+/*
+** Attach a table to a session. All subsequent changes made to the table
+** while the session object is enabled will be recorded.
+**
+** Only tables that have a PRIMARY KEY defined may be attached. It does
+** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
+** or not.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_attach(
+  sqlite3_session *pSession,      /* Session object */
+  const char *zName               /* Table name */
+){
+  int rc = SQLITE_OK;
+  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+
+  if( !zName ){
+    pSession->bAutoAttach = 1;
+  }else{
+    SessionTable *pTab;           /* New table object (if required) */
+    int nName;                    /* Number of bytes in string zName */
+
+    /* First search for an existing entry. If one is found, this call is
+    ** a no-op. Return early. */
+    nName = sqlite3Strlen30(zName);
+    for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
+      if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
+    }
+
+    if( !pTab ){
+      /* Allocate new SessionTable object. */
+      pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
+      if( !pTab ){
+        rc = SQLITE_NOMEM;
+      }else{
+        /* Populate the new SessionTable object and link it into the list.
+        ** The new object must be linked onto the end of the list, not 
+        ** simply added to the start of it in order to ensure that tables
+        ** appear in the correct order when a changeset or patchset is
+        ** eventually generated. */
+        SessionTable **ppTab;
+        memset(pTab, 0, sizeof(SessionTable));
+        pTab->zName = (char *)&pTab[1];
+        memcpy(pTab->zName, zName, nName+1);
+        for(ppTab=&pSession->pTable; *ppTab; ppTab=&(*ppTab)->pNext);
+        *ppTab = pTab;
+      }
+    }
+  }
+
+  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+  return rc;
+}
+
+/*
+** Ensure that there is room in the buffer to append nByte bytes of data.
+** If not, use sqlite3_realloc() to grow the buffer so that there is.
+**
+** If successful, return zero. Otherwise, if an OOM condition is encountered,
+** set *pRc to SQLITE_NOMEM and return non-zero.
+*/
+static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
+  if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
+    u8 *aNew;
+    int nNew = p->nAlloc ? p->nAlloc : 128;
+    do {
+      nNew = nNew*2;
+    }while( nNew<(p->nBuf+nByte) );
+
+    aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
+    if( 0==aNew ){
+      *pRc = SQLITE_NOMEM;
+    }else{
+      p->aBuf = aNew;
+      p->nAlloc = nNew;
+    }
+  }
+  return (*pRc!=SQLITE_OK);
+}
+
+/*
+** Append the value passed as the second argument to the buffer passed
+** as the first.
+**
+** This function is a no-op if *pRc is non-zero when it is called.
+** Otherwise, if an error occurs, *pRc is set to an SQLite error code
+** before returning.
+*/
+static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
+  int rc = *pRc;
+  if( rc==SQLITE_OK ){
+    int nByte = 0;
+    rc = sessionSerializeValue(0, pVal, &nByte);
+    sessionBufferGrow(p, nByte, &rc);
+    if( rc==SQLITE_OK ){
+      rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0);
+      p->nBuf += nByte;
+    }else{
+      *pRc = rc;
+    }
+  }
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is 
+** called. Otherwise, append a single byte to the buffer. 
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
+  if( 0==sessionBufferGrow(p, 1, pRc) ){
+    p->aBuf[p->nBuf++] = v;
+  }
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is 
+** called. Otherwise, append a single varint to the buffer. 
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){
+  if( 0==sessionBufferGrow(p, 9, pRc) ){
+    p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
+  }
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is 
+** called. Otherwise, append a blob of data to the buffer. 
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendBlob(
+  SessionBuffer *p, 
+  const u8 *aBlob, 
+  int nBlob, 
+  int *pRc
+){
+  if( 0==sessionBufferGrow(p, nBlob, pRc) ){
+    memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
+    p->nBuf += nBlob;
+  }
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is 
+** called. Otherwise, append a string to the buffer. All bytes in the string
+** up to (but not including) the nul-terminator are written to the buffer.
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendStr(
+  SessionBuffer *p, 
+  const char *zStr, 
+  int *pRc
+){
+  int nStr = sqlite3Strlen30(zStr);
+  if( 0==sessionBufferGrow(p, nStr, pRc) ){
+    memcpy(&p->aBuf[p->nBuf], zStr, nStr);
+    p->nBuf += nStr;
+  }
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is 
+** called. Otherwise, append the string representation of integer iVal
+** to the buffer. No nul-terminator is written.
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendInteger(
+  SessionBuffer *p,               /* Buffer to append to */
+  int iVal,                       /* Value to write the string rep. of */
+  int *pRc                        /* IN/OUT: Error code */
+){
+  char aBuf[24];
+  sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal);
+  sessionAppendStr(p, aBuf, pRc);
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is 
+** called. Otherwise, append the string zStr enclosed in quotes (") and
+** with any embedded quote characters escaped to the buffer. No 
+** nul-terminator byte is written.
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendIdent(
+  SessionBuffer *p,               /* Buffer to a append to */
+  const char *zStr,               /* String to quote, escape and append */
+  int *pRc                        /* IN/OUT: Error code */
+){
+  int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1;
+  if( 0==sessionBufferGrow(p, nStr, pRc) ){
+    char *zOut = (char *)&p->aBuf[p->nBuf];
+    const char *zIn = zStr;
+    *zOut++ = '"';
+    while( *zIn ){
+      if( *zIn=='"' ) *zOut++ = '"';
+      *zOut++ = *(zIn++);
+    }
+    *zOut++ = '"';
+    p->nBuf = (int)((u8 *)zOut - p->aBuf);
+  }
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is
+** called. Otherwse, it appends the serialized version of the value stored
+** in column iCol of the row that SQL statement pStmt currently points
+** to to the buffer.
+*/
+static void sessionAppendCol(
+  SessionBuffer *p,               /* Buffer to append to */
+  sqlite3_stmt *pStmt,            /* Handle pointing to row containing value */
+  int iCol,                       /* Column to read value from */
+  int *pRc                        /* IN/OUT: Error code */
+){
+  if( *pRc==SQLITE_OK ){
+    int eType = sqlite3_column_type(pStmt, iCol);
+    sessionAppendByte(p, (u8)eType, pRc);
+    if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+      sqlite3_int64 i;
+      u8 aBuf[8];
+      if( eType==SQLITE_INTEGER ){
+        i = sqlite3_column_int64(pStmt, iCol);
+      }else{
+        double r = sqlite3_column_double(pStmt, iCol);
+        memcpy(&i, &r, 8);
+      }
+      sessionPutI64(aBuf, i);
+      sessionAppendBlob(p, aBuf, 8, pRc);
+    }
+    if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){
+      u8 *z;
+      int nByte;
+      if( eType==SQLITE_BLOB ){
+        z = (u8 *)sqlite3_column_blob(pStmt, iCol);
+      }else{
+        z = (u8 *)sqlite3_column_text(pStmt, iCol);
+      }
+      nByte = sqlite3_column_bytes(pStmt, iCol);
+      if( z || (eType==SQLITE_BLOB && nByte==0) ){
+        sessionAppendVarint(p, nByte, pRc);
+        sessionAppendBlob(p, z, nByte, pRc);
+      }else{
+        *pRc = SQLITE_NOMEM;
+      }
+    }
+  }
+}
+
+/*
+**
+** This function appends an update change to the buffer (see the comments 
+** under "CHANGESET FORMAT" at the top of the file). An update change 
+** consists of:
+**
+**   1 byte:  SQLITE_UPDATE (0x17)
+**   n bytes: old.* record (see RECORD FORMAT)
+**   m bytes: new.* record (see RECORD FORMAT)
+**
+** The SessionChange object passed as the third argument contains the
+** values that were stored in the row when the session began (the old.*
+** values). The statement handle passed as the second argument points
+** at the current version of the row (the new.* values).
+**
+** If all of the old.* values are equal to their corresponding new.* value
+** (i.e. nothing has changed), then no data at all is appended to the buffer.
+**
+** Otherwise, the old.* record contains all primary key values and the 
+** original values of any fields that have been modified. The new.* record 
+** contains the new values of only those fields that have been modified.
+*/ 
+static int sessionAppendUpdate(
+  SessionBuffer *pBuf,            /* Buffer to append to */
+  int bPatchset,                  /* True for "patchset", 0 for "changeset" */
+  sqlite3_stmt *pStmt,            /* Statement handle pointing at new row */
+  SessionChange *p,               /* Object containing old values */
+  u8 *abPK                        /* Boolean array - true for PK columns */
+){
+  int rc = SQLITE_OK;
+  SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
+  int bNoop = 1;                /* Set to zero if any values are modified */
+  int nRewind = pBuf->nBuf;     /* Set to zero if any values are modified */
+  int i;                        /* Used to iterate through columns */
+  u8 *pCsr = p->aRecord;        /* Used to iterate through old.* values */
+
+  sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
+  sessionAppendByte(pBuf, p->bIndirect, &rc);
+  for(i=0; i<sqlite3_column_count(pStmt); i++){
+    int bChanged = 0;
+    int nAdvance;
+    int eType = *pCsr;
+    switch( eType ){
+      case SQLITE_NULL:
+        nAdvance = 1;
+        if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
+          bChanged = 1;
+        }
+        break;
+
+      case SQLITE_FLOAT:
+      case SQLITE_INTEGER: {
+        nAdvance = 9;
+        if( eType==sqlite3_column_type(pStmt, i) ){
+          sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
+          if( eType==SQLITE_INTEGER ){
+            if( iVal==sqlite3_column_int64(pStmt, i) ) break;
+          }else{
+            double dVal;
+            memcpy(&dVal, &iVal, 8);
+            if( dVal==sqlite3_column_double(pStmt, i) ) break;
+          }
+        }
+        bChanged = 1;
+        break;
+      }
+
+      default: {
+        int nByte;
+        int nHdr = 1 + sessionVarintGet(&pCsr[1], &nByte);
+        assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
+        nAdvance = nHdr + nByte;
+        if( eType==sqlite3_column_type(pStmt, i) 
+         && nByte==sqlite3_column_bytes(pStmt, i) 
+         && 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), nByte)
+        ){
+          break;
+        }
+        bChanged = 1;
+      }
+    }
+
+    /* If at least one field has been modified, this is not a no-op. */
+    if( bChanged ) bNoop = 0;
+
+    /* Add a field to the old.* record. This is omitted if this modules is
+    ** currently generating a patchset. */
+    if( bPatchset==0 ){
+      if( bChanged || abPK[i] ){
+        sessionAppendBlob(pBuf, pCsr, nAdvance, &rc);
+      }else{
+        sessionAppendByte(pBuf, 0, &rc);
+      }
+    }
+
+    /* Add a field to the new.* record. Or the only record if currently
+    ** generating a patchset.  */
+    if( bChanged || (bPatchset && abPK[i]) ){
+      sessionAppendCol(&buf2, pStmt, i, &rc);
+    }else{
+      sessionAppendByte(&buf2, 0, &rc);
+    }
+
+    pCsr += nAdvance;
+  }
+
+  if( bNoop ){
+    pBuf->nBuf = nRewind;
+  }else{
+    sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc);
+  }
+  sqlite3_free(buf2.aBuf);
+
+  return rc;
+}
+
+/*
+** Append a DELETE change to the buffer passed as the first argument. Use
+** the changeset format if argument bPatchset is zero, or the patchset
+** format otherwise.
+*/
+static int sessionAppendDelete(
+  SessionBuffer *pBuf,            /* Buffer to append to */
+  int bPatchset,                  /* True for "patchset", 0 for "changeset" */
+  SessionChange *p,               /* Object containing old values */
+  int nCol,                       /* Number of columns in table */
+  u8 *abPK                        /* Boolean array - true for PK columns */
+){
+  int rc = SQLITE_OK;
+
+  sessionAppendByte(pBuf, SQLITE_DELETE, &rc);
+  sessionAppendByte(pBuf, p->bIndirect, &rc);
+
+  if( bPatchset==0 ){
+    sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc);
+  }else{
+    int i;
+    u8 *a = p->aRecord;
+    for(i=0; i<nCol; i++){
+      u8 *pStart = a;
+      int eType = *a++;
+
+      switch( eType ){
+        case 0:
+        case SQLITE_NULL:
+          assert( abPK[i]==0 );
+          break;
+
+        case SQLITE_FLOAT:
+        case SQLITE_INTEGER:
+          a += 8;
+          break;
+
+        default: {
+          int n;
+          a += sessionVarintGet(a, &n);
+          a += n;
+          break;
+        }
+      }
+      if( abPK[i] ){
+        sessionAppendBlob(pBuf, pStart, (int)(a-pStart), &rc);
+      }
+    }
+    assert( (a - p->aRecord)==p->nRecord );
+  }
+
+  return rc;
+}
+
+/*
+** Formulate and prepare a SELECT statement to retrieve a row from table
+** zTab in database zDb based on its primary key. i.e.
+**
+**   SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ...
+*/
+static int sessionSelectStmt(
+  sqlite3 *db,                    /* Database handle */
+  const char *zDb,                /* Database name */
+  const char *zTab,               /* Table name */
+  int nCol,                       /* Number of columns in table */
+  const char **azCol,             /* Names of table columns */
+  u8 *abPK,                       /* PRIMARY KEY  array */
+  sqlite3_stmt **ppStmt           /* OUT: Prepared SELECT statement */
+){
+  int rc = SQLITE_OK;
+  int i;
+  const char *zSep = "";
+  SessionBuffer buf = {0, 0, 0};
+
+  sessionAppendStr(&buf, "SELECT * FROM ", &rc);
+  sessionAppendIdent(&buf, zDb, &rc);
+  sessionAppendStr(&buf, ".", &rc);
+  sessionAppendIdent(&buf, zTab, &rc);
+  sessionAppendStr(&buf, " WHERE ", &rc);
+  for(i=0; i<nCol; i++){
+    if( abPK[i] ){
+      sessionAppendStr(&buf, zSep, &rc);
+      sessionAppendIdent(&buf, azCol[i], &rc);
+      sessionAppendStr(&buf, " = ?", &rc);
+      sessionAppendInteger(&buf, i+1, &rc);
+      zSep = " AND ";
+    }
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0);
+  }
+  sqlite3_free(buf.aBuf);
+  return rc;
+}
+
+/*
+** Bind the PRIMARY KEY values from the change passed in argument pChange
+** to the SELECT statement passed as the first argument. The SELECT statement
+** is as prepared by function sessionSelectStmt().
+**
+** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
+** error code (e.g. SQLITE_NOMEM) otherwise.
+*/
+static int sessionSelectBind(
+  sqlite3_stmt *pSelect,          /* SELECT from sessionSelectStmt() */
+  int nCol,                       /* Number of columns in table */
+  u8 *abPK,                       /* PRIMARY KEY array */
+  SessionChange *pChange          /* Change structure */
+){
+  int i;
+  int rc = SQLITE_OK;
+  u8 *a = pChange->aRecord;
+
+  for(i=0; i<nCol && rc==SQLITE_OK; i++){
+    int eType = *a++;
+
+    switch( eType ){
+      case 0:
+      case SQLITE_NULL:
+        assert( abPK[i]==0 );
+        break;
+
+      case SQLITE_INTEGER: {
+        if( abPK[i] ){
+          i64 iVal = sessionGetI64(a);
+          rc = sqlite3_bind_int64(pSelect, i+1, iVal);
+        }
+        a += 8;
+        break;
+      }
+
+      case SQLITE_FLOAT: {
+        if( abPK[i] ){
+          double rVal;
+          i64 iVal = sessionGetI64(a);
+          memcpy(&rVal, &iVal, 8);
+          rc = sqlite3_bind_double(pSelect, i+1, rVal);
+        }
+        a += 8;
+        break;
+      }
+
+      case SQLITE_TEXT: {
+        int n;
+        a += sessionVarintGet(a, &n);
+        if( abPK[i] ){
+          rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT);
+        }
+        a += n;
+        break;
+      }
+
+      default: {
+        int n;
+        assert( eType==SQLITE_BLOB );
+        a += sessionVarintGet(a, &n);
+        if( abPK[i] ){
+          rc = sqlite3_bind_blob(pSelect, i+1, a, n, SQLITE_TRANSIENT);
+        }
+        a += n;
+        break;
+      }
+    }
+  }
+
+  return rc;
+}
+
+/*
+** This function is a no-op if *pRc is set to other than SQLITE_OK when it
+** is called. Otherwise, append a serialized table header (part of the binary 
+** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an
+** SQLite error code before returning.
+*/
+static void sessionAppendTableHdr(
+  SessionBuffer *pBuf,            /* Append header to this buffer */
+  int bPatchset,                  /* Use the patchset format if true */
+  SessionTable *pTab,             /* Table object to append header for */
+  int *pRc                        /* IN/OUT: Error code */
+){
+  /* Write a table header */
+  sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc);
+  sessionAppendVarint(pBuf, pTab->nCol, pRc);
+  sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc);
+  sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc);
+}
+
+/*
+** Generate either a changeset (if argument bPatchset is zero) or a patchset
+** (if it is non-zero) based on the current contents of the session object
+** passed as the first argument.
+**
+** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
+** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
+** occurs, an SQLite error code is returned and both output variables set 
+** to 0.
+*/
+static int sessionGenerateChangeset(
+  sqlite3_session *pSession,      /* Session object */
+  int bPatchset,                  /* True for patchset, false for changeset */
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut,                     /* First argument for xOutput */
+  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
+  void **ppChangeset              /* OUT: Buffer containing changeset */
+){
+  sqlite3 *db = pSession->db;     /* Source database handle */
+  SessionTable *pTab;             /* Used to iterate through attached tables */
+  SessionBuffer buf = {0,0,0};    /* Buffer in which to accumlate changeset */
+  int rc;                         /* Return code */
+
+  assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) );
+
+  /* Zero the output variables in case an error occurs. If this session
+  ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
+  ** this call will be a no-op.  */
+  if( xOutput==0 ){
+    *pnChangeset = 0;
+    *ppChangeset = 0;
+  }
+
+  if( pSession->rc ) return pSession->rc;
+  rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0);
+  if( rc!=SQLITE_OK ) return rc;
+
+  sqlite3_mutex_enter(sqlite3_db_mutex(db));
+
+  for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
+    if( pTab->nEntry ){
+      const char *zName = pTab->zName;
+      int nCol;                   /* Number of columns in table */
+      u8 *abPK;                   /* Primary key array */
+      const char **azCol = 0;     /* Table columns */
+      int i;                      /* Used to iterate through hash buckets */
+      sqlite3_stmt *pSel = 0;     /* SELECT statement to query table pTab */
+      int nRewind = buf.nBuf;     /* Initial size of write buffer */
+      int nNoop;                  /* Size of buffer after writing tbl header */
+
+      /* Check the table schema is still Ok. */
+      rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK);
+      if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
+        rc = SQLITE_SCHEMA;
+      }
+
+      /* Write a table header */
+      sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
+
+      /* Build and compile a statement to execute: */
+      if( rc==SQLITE_OK ){
+        rc = sessionSelectStmt(
+            db, pSession->zDb, zName, nCol, azCol, abPK, &pSel);
+      }
+
+      nNoop = buf.nBuf;
+      for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
+        SessionChange *p;         /* Used to iterate through changes */
+
+        for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
+          rc = sessionSelectBind(pSel, nCol, abPK, p);
+          if( rc!=SQLITE_OK ) continue;
+          if( sqlite3_step(pSel)==SQLITE_ROW ){
+            if( p->op==SQLITE_INSERT ){
+              int iCol;
+              sessionAppendByte(&buf, SQLITE_INSERT, &rc);
+              sessionAppendByte(&buf, p->bIndirect, &rc);
+              for(iCol=0; iCol<nCol; iCol++){
+                sessionAppendCol(&buf, pSel, iCol, &rc);
+              }
+            }else{
+              rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
+            }
+          }else if( p->op!=SQLITE_INSERT ){
+            rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
+          }
+          if( rc==SQLITE_OK ){
+            rc = sqlite3_reset(pSel);
+          }
+
+          /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
+          ** its contents to the xOutput() callback. */
+          if( xOutput 
+           && rc==SQLITE_OK 
+           && buf.nBuf>nNoop 
+           && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE 
+          ){
+            rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
+            nNoop = -1;
+            buf.nBuf = 0;
+          }
+
+        }
+      }
+
+      sqlite3_finalize(pSel);
+      if( buf.nBuf==nNoop ){
+        buf.nBuf = nRewind;
+      }
+      sqlite3_free((char*)azCol);  /* cast works around VC++ bug */
+    }
+  }
+
+  if( rc==SQLITE_OK ){
+    if( xOutput==0 ){
+      *pnChangeset = buf.nBuf;
+      *ppChangeset = buf.aBuf;
+      buf.aBuf = 0;
+    }else if( buf.nBuf>0 ){
+      rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
+    }
+  }
+
+  sqlite3_free(buf.aBuf);
+  sqlite3_exec(db, "RELEASE changeset", 0, 0, 0);
+  sqlite3_mutex_leave(sqlite3_db_mutex(db));
+  return rc;
+}
+
+/*
+** Obtain a changeset object containing all changes recorded by the 
+** session object passed as the first argument.
+**
+** It is the responsibility of the caller to eventually free the buffer 
+** using sqlite3_free().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_changeset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
+  void **ppChangeset              /* OUT: Buffer containing changeset */
+){
+  return sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset);
+}
+
+/*
+** Streaming version of sqlite3session_changeset().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_changeset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+){
+  return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
+}
+
+/*
+** Streaming version of sqlite3session_patchset().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_patchset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+){
+  return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
+}
+
+/*
+** Obtain a patchset object containing all changes recorded by the 
+** session object passed as the first argument.
+**
+** It is the responsibility of the caller to eventually free the buffer 
+** using sqlite3_free().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_patchset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
+  void **ppPatchset               /* OUT: Buffer containing changeset */
+){
+  return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
+}
+
+/*
+** Enable or disable the session object passed as the first argument.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_enable(sqlite3_session *pSession, int bEnable){
+  int ret;
+  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+  if( bEnable>=0 ){
+    pSession->bEnable = bEnable;
+  }
+  ret = pSession->bEnable;
+  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+  return ret;
+}
+
+/*
+** Enable or disable the session object passed as the first argument.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
+  int ret;
+  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+  if( bIndirect>=0 ){
+    pSession->bIndirect = bIndirect;
+  }
+  ret = pSession->bIndirect;
+  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+  return ret;
+}
+
+/*
+** Return true if there have been no changes to monitored tables recorded
+** by the session object passed as the only argument.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3session_isempty(sqlite3_session *pSession){
+  int ret = 0;
+  SessionTable *pTab;
+
+  sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+  for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
+    ret = (pTab->nEntry>0);
+  }
+  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+
+  return (ret==0);
+}
+
+/*
+** Do the work for either sqlite3changeset_start() or start_strm().
+*/
+static int sessionChangesetStart(
+  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn,
+  int nChangeset,                 /* Size of buffer pChangeset in bytes */
+  void *pChangeset                /* Pointer to buffer containing changeset */
+){
+  sqlite3_changeset_iter *pRet;   /* Iterator to return */
+  int nByte;                      /* Number of bytes to allocate for iterator */
+
+  assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
+
+  /* Zero the output variable in case an error occurs. */
+  *pp = 0;
+
+  /* Allocate and initialize the iterator structure. */
+  nByte = sizeof(sqlite3_changeset_iter);
+  pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
+  if( !pRet ) return SQLITE_NOMEM;
+  memset(pRet, 0, sizeof(sqlite3_changeset_iter));
+  pRet->in.aData = (u8 *)pChangeset;
+  pRet->in.nData = nChangeset;
+  pRet->in.xInput = xInput;
+  pRet->in.pIn = pIn;
+  pRet->in.bEof = (xInput ? 0 : 1);
+
+  /* Populate the output variable and return success. */
+  *pp = pRet;
+  return SQLITE_OK;
+}
+
+/*
+** Create an iterator used to iterate through the contents of a changeset.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_start(
+  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
+  int nChangeset,                 /* Size of buffer pChangeset in bytes */
+  void *pChangeset                /* Pointer to buffer containing changeset */
+){
+  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
+}
+
+/*
+** Streaming version of sqlite3changeset_start().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_start_strm(
+  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn
+){
+  return sessionChangesetStart(pp, xInput, pIn, 0, 0);
+}
+
+/*
+** If the SessionInput object passed as the only argument is a streaming
+** object and the buffer is full, discard some data to free up space.
+*/
+static void sessionDiscardData(SessionInput *pIn){
+  if( pIn->bEof && pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
+    int nMove = pIn->buf.nBuf - pIn->iNext;
+    assert( nMove>=0 );
+    if( nMove>0 ){
+      memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
+    }
+    pIn->buf.nBuf -= pIn->iNext;
+    pIn->iNext = 0;
+    pIn->nData = pIn->buf.nBuf;
+  }
+}
+
+/*
+** Ensure that there are at least nByte bytes available in the buffer. Or,
+** if there are not nByte bytes remaining in the input, that all available
+** data is in the buffer.
+**
+** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
+*/
+static int sessionInputBuffer(SessionInput *pIn, int nByte){
+  int rc = SQLITE_OK;
+  if( pIn->xInput ){
+    while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
+      int nNew = SESSIONS_STRM_CHUNK_SIZE;
+
+      if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
+      if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
+        rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
+        if( nNew==0 ){
+          pIn->bEof = 1;
+        }else{
+          pIn->buf.nBuf += nNew;
+        }
+      }
+
+      pIn->aData = pIn->buf.aBuf;
+      pIn->nData = pIn->buf.nBuf;
+    }
+  }
+  return rc;
+}
+
+/*
+** When this function is called, *ppRec points to the start of a record
+** that contains nCol values. This function advances the pointer *ppRec
+** until it points to the byte immediately following that record.
+*/
+static void sessionSkipRecord(
+  u8 **ppRec,                     /* IN/OUT: Record pointer */
+  int nCol                        /* Number of values in record */
+){
+  u8 *aRec = *ppRec;
+  int i;
+  for(i=0; i<nCol; i++){
+    int eType = *aRec++;
+    if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+      int nByte;
+      aRec += sessionVarintGet((u8*)aRec, &nByte);
+      aRec += nByte;
+    }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+      aRec += 8;
+    }
+  }
+
+  *ppRec = aRec;
+}
+
+/*
+** This function sets the value of the sqlite3_value object passed as the
+** first argument to a copy of the string or blob held in the aData[] 
+** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM
+** error occurs.
+*/
+static int sessionValueSetStr(
+  sqlite3_value *pVal,            /* Set the value of this object */
+  u8 *aData,                      /* Buffer containing string or blob data */
+  int nData,                      /* Size of buffer aData[] in bytes */
+  u8 enc                          /* String encoding (0 for blobs) */
+){
+  /* In theory this code could just pass SQLITE_TRANSIENT as the final
+  ** argument to sqlite3ValueSetStr() and have the copy created 
+  ** automatically. But doing so makes it difficult to detect any OOM
+  ** error. Hence the code to create the copy externally. */
+  u8 *aCopy = sqlite3_malloc(nData+1);
+  if( aCopy==0 ) return SQLITE_NOMEM;
+  memcpy(aCopy, aData, nData);
+  sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
+  return SQLITE_OK;
+}
+
+/*
+** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
+** for details.
+**
+** When this function is called, *paChange points to the start of the record
+** to deserialize. Assuming no error occurs, *paChange is set to point to
+** one byte after the end of the same record before this function returns.
+** If the argument abPK is NULL, then the record contains nCol values. Or,
+** if abPK is other than NULL, then the record contains only the PK fields
+** (in other words, it is a patchset DELETE record).
+**
+** If successful, each element of the apOut[] array (allocated by the caller)
+** is set to point to an sqlite3_value object containing the value read
+** from the corresponding position in the record. If that value is not
+** included in the record (i.e. because the record is part of an UPDATE change
+** and the field was not modified), the corresponding element of apOut[] is
+** set to NULL.
+**
+** It is the responsibility of the caller to free all sqlite_value structures
+** using sqlite3_free().
+**
+** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
+** The apOut[] array may have been partially populated in this case.
+*/
+static int sessionReadRecord(
+  SessionInput *pIn,              /* Input data */
+  int nCol,                       /* Number of values in record */
+  u8 *abPK,                       /* Array of primary key flags, or NULL */
+  sqlite3_value **apOut           /* Write values to this array */
+){
+  int i;                          /* Used to iterate through columns */
+  int rc = SQLITE_OK;
+
+  for(i=0; i<nCol && rc==SQLITE_OK; i++){
+    int eType = 0;                /* Type of value (SQLITE_NULL, TEXT etc.) */
+    if( abPK && abPK[i]==0 ) continue;
+    rc = sessionInputBuffer(pIn, 9);
+    if( rc==SQLITE_OK ){
+      eType = pIn->aData[pIn->iNext++];
+    }
+
+    assert( apOut[i]==0 );
+    if( eType ){
+      apOut[i] = sqlite3ValueNew(0);
+      if( !apOut[i] ) rc = SQLITE_NOMEM;
+    }
+
+    if( rc==SQLITE_OK ){
+      u8 *aVal = &pIn->aData[pIn->iNext];
+      if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+        int nByte;
+        pIn->iNext += sessionVarintGet(aVal, &nByte);
+        rc = sessionInputBuffer(pIn, nByte);
+        if( rc==SQLITE_OK ){
+          u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
+          rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
+        }
+        pIn->iNext += nByte;
+      }
+      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+        sqlite3_int64 v = sessionGetI64(aVal);
+        if( eType==SQLITE_INTEGER ){
+          sqlite3VdbeMemSetInt64(apOut[i], v);
+        }else{
+          double d;
+          memcpy(&d, &v, 8);
+          sqlite3VdbeMemSetDouble(apOut[i], d);
+        }
+        pIn->iNext += 8;
+      }
+    }
+  }
+
+  return rc;
+}
+
+/*
+** The input pointer currently points to the second byte of a table-header.
+** Specifically, to the following:
+**
+**   + number of columns in table (varint)
+**   + array of PK flags (1 byte per column),
+**   + table name (nul terminated).
+**
+** This function ensures that all of the above is present in the input 
+** buffer (i.e. that it can be accessed without any calls to xInput()).
+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
+** The input pointer is not moved.
+*/
+static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
+  int rc = SQLITE_OK;
+  int nCol = 0;
+  int nRead = 0;
+
+  rc = sessionInputBuffer(pIn, 9);
+  if( rc==SQLITE_OK ){
+    nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
+    rc = sessionInputBuffer(pIn, nRead+nCol+100);
+    nRead += nCol;
+  }
+
+  while( rc==SQLITE_OK ){
+    while( (pIn->iNext + nRead)<pIn->nData && pIn->aData[pIn->iNext + nRead] ){
+      nRead++;
+    }
+    if( (pIn->iNext + nRead)<pIn->nData ) break;
+    rc = sessionInputBuffer(pIn, nRead + 100);
+  }
+  *pnByte = nRead+1;
+  return rc;
+}
+
+/*
+** The input pointer currently points to the first byte of the first field
+** of a record consisting of nCol columns. This function ensures the entire
+** record is buffered. It does not move the input pointer.
+**
+** If successful, SQLITE_OK is returned and *pnByte is set to the size of
+** the record in bytes. Otherwise, an SQLite error code is returned. The
+** final value of *pnByte is undefined in this case.
+*/
+static int sessionChangesetBufferRecord(
+  SessionInput *pIn,              /* Input data */
+  int nCol,                       /* Number of columns in record */
+  int *pnByte                     /* OUT: Size of record in bytes */
+){
+  int rc = SQLITE_OK;
+  int nByte = 0;
+  int i;
+  for(i=0; rc==SQLITE_OK && i<nCol; i++){
+    int eType;
+    rc = sessionInputBuffer(pIn, nByte + 10);
+    if( rc==SQLITE_OK ){
+      eType = pIn->aData[pIn->iNext + nByte++];
+      if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+        int n;
+        nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n);
+        nByte += n;
+        rc = sessionInputBuffer(pIn, nByte);
+      }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+        nByte += 8;
+      }
+    }
+  }
+  *pnByte = nByte;
+  return rc;
+}
+
+/*
+** The input pointer currently points to the second byte of a table-header.
+** Specifically, to the following:
+**
+**   + number of columns in table (varint)
+**   + array of PK flags (1 byte per column),
+**   + table name (nul terminated).
+**
+** This function decodes the table-header and populates the p->nCol, 
+** p->zTab and p->abPK[] variables accordingly. The p->apValue[] array is 
+** also allocated or resized according to the new value of p->nCol. The
+** input pointer is left pointing to the byte following the table header.
+**
+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code
+** is returned and the final values of the various fields enumerated above
+** are undefined.
+*/
+static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
+  int rc;
+  int nCopy;
+  assert( p->rc==SQLITE_OK );
+
+  rc = sessionChangesetBufferTblhdr(&p->in, &nCopy);
+  if( rc==SQLITE_OK ){
+    int nByte;
+    int nVarint;
+    nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
+    nCopy -= nVarint;
+    p->in.iNext += nVarint;
+    nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
+    p->tblhdr.nBuf = 0;
+    sessionBufferGrow(&p->tblhdr, nByte, &rc);
+  }
+
+  if( rc==SQLITE_OK ){
+    int iPK = sizeof(sqlite3_value*)*p->nCol*2;
+    memset(p->tblhdr.aBuf, 0, iPK);
+    memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
+    p->in.iNext += nCopy;
+  }
+
+  p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
+  p->abPK = (u8*)&p->apValue[p->nCol*2];
+  p->zTab = (char*)&p->abPK[p->nCol];
+  return (p->rc = rc);
+}
+
+/*
+** Advance the changeset iterator to the next change.
+**
+** If both paRec and pnRec are NULL, then this function works like the public
+** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the
+** sqlite3changeset_new() and old() APIs may be used to query for values.
+**
+** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change
+** record is written to *paRec before returning and the number of bytes in
+** the record to *pnRec.
+**
+** Either way, this function returns SQLITE_ROW if the iterator is 
+** successfully advanced to the next change in the changeset, an SQLite 
+** error code if an error occurs, or SQLITE_DONE if there are no further 
+** changes in the changeset.
+*/
+static int sessionChangesetNext(
+  sqlite3_changeset_iter *p,      /* Changeset iterator */
+  u8 **paRec,                     /* If non-NULL, store record pointer here */
+  int *pnRec                      /* If non-NULL, store size of record here */
+){
+  int i;
+  u8 op;
+
+  assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );
+
+  /* If the iterator is in the error-state, return immediately. */
+  if( p->rc!=SQLITE_OK ) return p->rc;
+
+  /* Free the current contents of p->apValue[], if any. */
+  if( p->apValue ){
+    for(i=0; i<p->nCol*2; i++){
+      sqlite3ValueFree(p->apValue[i]);
+    }
+    memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2);
+  }
+
+  /* Make sure the buffer contains at least 10 bytes of input data, or all
+  ** remaining data if there are less than 10 bytes available. This is
+  ** sufficient either for the 'T' or 'P' byte and the varint that follows
+  ** it, or for the two single byte values otherwise. */
+  p->rc = sessionInputBuffer(&p->in, 2);
+  if( p->rc!=SQLITE_OK ) return p->rc;
+
+  /* If the iterator is already at the end of the changeset, return DONE. */
+  if( p->in.iNext>=p->in.nData ){
+    return SQLITE_DONE;
+  }
+
+  sessionDiscardData(&p->in);
+  p->in.iCurrent = p->in.iNext;
+
+  op = p->in.aData[p->in.iNext++];
+  if( op=='T' || op=='P' ){
+    p->bPatchset = (op=='P');
+    if( sessionChangesetReadTblhdr(p) ) return p->rc;
+    if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
+    p->in.iCurrent = p->in.iNext;
+    op = p->in.aData[p->in.iNext++];
+  }
+
+  p->op = op;
+  p->bIndirect = p->in.aData[p->in.iNext++];
+  if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
+    return (p->rc = SQLITE_CORRUPT_BKPT);
+  }
+
+  if( paRec ){ 
+    int nVal;                     /* Number of values to buffer */
+    if( p->bPatchset==0 && op==SQLITE_UPDATE ){
+      nVal = p->nCol * 2;
+    }else if( p->bPatchset && op==SQLITE_DELETE ){
+      nVal = 0;
+      for(i=0; i<p->nCol; i++) if( p->abPK[i] ) nVal++;
+    }else{
+      nVal = p->nCol;
+    }
+    p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
+    if( p->rc!=SQLITE_OK ) return p->rc;
+    *paRec = &p->in.aData[p->in.iNext];
+    p->in.iNext += *pnRec;
+  }else{
+
+    /* If this is an UPDATE or DELETE, read the old.* record. */
+    if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
+      u8 *abPK = p->bPatchset ? p->abPK : 0;
+      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
+      if( p->rc!=SQLITE_OK ) return p->rc;
+    }
+
+    /* If this is an INSERT or UPDATE, read the new.* record. */
+    if( p->op!=SQLITE_DELETE ){
+      p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
+      if( p->rc!=SQLITE_OK ) return p->rc;
+    }
+
+    if( p->bPatchset && p->op==SQLITE_UPDATE ){
+      /* If this is an UPDATE that is part of a patchset, then all PK and
+      ** modified fields are present in the new.* record. The old.* record
+      ** is currently completely empty. This block shifts the PK fields from
+      ** new.* to old.*, to accommodate the code that reads these arrays.  */
+      for(i=0; i<p->nCol; i++){
+        assert( p->apValue[i]==0 );
+        assert( p->abPK[i]==0 || p->apValue[i+p->nCol] );
+        if( p->abPK[i] ){
+          p->apValue[i] = p->apValue[i+p->nCol];
+          p->apValue[i+p->nCol] = 0;
+        }
+      }
+    }
+  }
+
+  return SQLITE_ROW;
+}
+
+/*
+** Advance an iterator created by sqlite3changeset_start() to the next
+** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
+** or SQLITE_CORRUPT.
+**
+** This function may not be called on iterators passed to a conflict handler
+** callback by changeset_apply().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_next(sqlite3_changeset_iter *p){
+  return sessionChangesetNext(p, 0, 0);
+}
+
+/*
+** The following function extracts information on the current change
+** from a changeset iterator. It may only be called after changeset_next()
+** has returned SQLITE_ROW.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_op(
+  sqlite3_changeset_iter *pIter,  /* Iterator handle */
+  const char **pzTab,             /* OUT: Pointer to table name */
+  int *pnCol,                     /* OUT: Number of columns in table */
+  int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
+  int *pbIndirect                 /* OUT: True if change is indirect */
+){
+  *pOp = pIter->op;
+  *pnCol = pIter->nCol;
+  *pzTab = pIter->zTab;
+  if( pbIndirect ) *pbIndirect = pIter->bIndirect;
+  return SQLITE_OK;
+}
+
+/*
+** Return information regarding the PRIMARY KEY and number of columns in
+** the database table affected by the change that pIter currently points
+** to. This function may only be called after changeset_next() returns
+** SQLITE_ROW.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_pk(
+  sqlite3_changeset_iter *pIter,  /* Iterator object */
+  unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
+  int *pnCol                      /* OUT: Number of entries in output array */
+){
+  *pabPK = pIter->abPK;
+  if( pnCol ) *pnCol = pIter->nCol;
+  return SQLITE_OK;
+}
+
+/*
+** This function may only be called while the iterator is pointing to an
+** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
+** Otherwise, SQLITE_MISUSE is returned.
+**
+** It sets *ppValue to point to an sqlite3_value structure containing the
+** iVal'th value in the old.* record. Or, if that particular value is not
+** included in the record (because the change is an UPDATE and the field
+** was not modified and is not a PK column), set *ppValue to NULL.
+**
+** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
+** not modified. Otherwise, SQLITE_OK.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_old(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Index of old.* value to retrieve */
+  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
+){
+  if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){
+    return SQLITE_MISUSE;
+  }
+  if( iVal<0 || iVal>=pIter->nCol ){
+    return SQLITE_RANGE;
+  }
+  *ppValue = pIter->apValue[iVal];
+  return SQLITE_OK;
+}
+
+/*
+** This function may only be called while the iterator is pointing to an
+** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()).
+** Otherwise, SQLITE_MISUSE is returned.
+**
+** It sets *ppValue to point to an sqlite3_value structure containing the
+** iVal'th value in the new.* record. Or, if that particular value is not
+** included in the record (because the change is an UPDATE and the field
+** was not modified), set *ppValue to NULL.
+**
+** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
+** not modified. Otherwise, SQLITE_OK.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_new(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Index of new.* value to retrieve */
+  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
+){
+  if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){
+    return SQLITE_MISUSE;
+  }
+  if( iVal<0 || iVal>=pIter->nCol ){
+    return SQLITE_RANGE;
+  }
+  *ppValue = pIter->apValue[pIter->nCol+iVal];
+  return SQLITE_OK;
+}
+
+/*
+** The following two macros are used internally. They are similar to the
+** sqlite3changeset_new() and sqlite3changeset_old() functions, except that
+** they omit all error checking and return a pointer to the requested value.
+*/
+#define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)]
+#define sessionChangesetOld(pIter, iVal) (pIter)->apValue[(iVal)]
+
+/*
+** This function may only be called with a changeset iterator that has been
+** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT 
+** conflict-handler function. Otherwise, SQLITE_MISUSE is returned.
+**
+** If successful, *ppValue is set to point to an sqlite3_value structure
+** containing the iVal'th value of the conflicting record.
+**
+** If value iVal is out-of-range or some other error occurs, an SQLite error
+** code is returned. Otherwise, SQLITE_OK.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_conflict(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Index of conflict record value to fetch */
+  sqlite3_value **ppValue         /* OUT: Value from conflicting row */
+){
+  if( !pIter->pConflict ){
+    return SQLITE_MISUSE;
+  }
+  if( iVal<0 || iVal>=sqlite3_column_count(pIter->pConflict) ){
+    return SQLITE_RANGE;
+  }
+  *ppValue = sqlite3_column_value(pIter->pConflict, iVal);
+  return SQLITE_OK;
+}
+
+/*
+** This function may only be called with an iterator passed to an
+** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+** it sets the output variable to the total number of known foreign key
+** violations in the destination database and returns SQLITE_OK.
+**
+** In all other cases this function returns SQLITE_MISUSE.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_fk_conflicts(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int *pnOut                      /* OUT: Number of FK violations */
+){
+  if( pIter->pConflict || pIter->apValue ){
+    return SQLITE_MISUSE;
+  }
+  *pnOut = pIter->nCol;
+  return SQLITE_OK;
+}
+
+
+/*
+** Finalize an iterator allocated with sqlite3changeset_start().
+**
+** This function may not be called on iterators passed to a conflict handler
+** callback by changeset_apply().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_finalize(sqlite3_changeset_iter *p){
+  int rc = SQLITE_OK;
+  if( p ){
+    int i;                        /* Used to iterate through p->apValue[] */
+    rc = p->rc;
+    if( p->apValue ){
+      for(i=0; i<p->nCol*2; i++) sqlite3ValueFree(p->apValue[i]);
+    }
+    sqlite3_free(p->tblhdr.aBuf);
+    sqlite3_free(p->in.buf.aBuf);
+    sqlite3_free(p);
+  }
+  return rc;
+}
+
+static int sessionChangesetInvert(
+  SessionInput *pInput,           /* Input changeset */
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut,
+  int *pnInverted,                /* OUT: Number of bytes in output changeset */
+  void **ppInverted               /* OUT: Inverse of pChangeset */
+){
+  int rc = SQLITE_OK;             /* Return value */
+  SessionBuffer sOut;             /* Output buffer */
+  int nCol = 0;                   /* Number of cols in current table */
+  u8 *abPK = 0;                   /* PK array for current table */
+  sqlite3_value **apVal = 0;      /* Space for values for UPDATE inversion */
+  SessionBuffer sPK = {0, 0, 0};  /* PK array for current table */
+
+  /* Initialize the output buffer */
+  memset(&sOut, 0, sizeof(SessionBuffer));
+
+  /* Zero the output variables in case an error occurs. */
+  if( ppInverted ){
+    *ppInverted = 0;
+    *pnInverted = 0;
+  }
+
+  while( 1 ){
+    u8 eType;
+
+    /* Test for EOF. */
+    if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert;
+    if( pInput->iNext>=pInput->nData ) break;
+    eType = pInput->aData[pInput->iNext];
+
+    switch( eType ){
+      case 'T': {
+        /* A 'table' record consists of:
+        **
+        **   * A constant 'T' character,
+        **   * Number of columns in said table (a varint),
+        **   * An array of nCol bytes (sPK),
+        **   * A nul-terminated table name.
+        */
+        int nByte;
+        int nVar;
+        pInput->iNext++;
+        if( (rc = sessionChangesetBufferTblhdr(pInput, &nByte)) ){
+          goto finished_invert;
+        }
+        nVar = sessionVarintGet(&pInput->aData[pInput->iNext], &nCol);
+        sPK.nBuf = 0;
+        sessionAppendBlob(&sPK, &pInput->aData[pInput->iNext+nVar], nCol, &rc);
+        sessionAppendByte(&sOut, eType, &rc);
+        sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
+        if( rc ) goto finished_invert;
+
+        pInput->iNext += nByte;
+        sqlite3_free(apVal);
+        apVal = 0;
+        abPK = sPK.aBuf;
+        break;
+      }
+
+      case SQLITE_INSERT:
+      case SQLITE_DELETE: {
+        int nByte;
+        int bIndirect = pInput->aData[pInput->iNext+1];
+        int eType2 = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE);
+        pInput->iNext += 2;
+        assert( rc==SQLITE_OK );
+        rc = sessionChangesetBufferRecord(pInput, nCol, &nByte);
+        sessionAppendByte(&sOut, eType2, &rc);
+        sessionAppendByte(&sOut, bIndirect, &rc);
+        sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
+        pInput->iNext += nByte;
+        if( rc ) goto finished_invert;
+        break;
+      }
+
+      case SQLITE_UPDATE: {
+        int iCol;
+
+        if( 0==apVal ){
+          apVal = (sqlite3_value **)sqlite3_malloc(sizeof(apVal[0])*nCol*2);
+          if( 0==apVal ){
+            rc = SQLITE_NOMEM;
+            goto finished_invert;
+          }
+          memset(apVal, 0, sizeof(apVal[0])*nCol*2);
+        }
+
+        /* Write the header for the new UPDATE change. Same as the original. */
+        sessionAppendByte(&sOut, eType, &rc);
+        sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);
+
+        /* Read the old.* and new.* records for the update change. */
+        pInput->iNext += 2;
+        rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]);
+        if( rc==SQLITE_OK ){
+          rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol]);
+        }
+
+        /* Write the new old.* record. Consists of the PK columns from the
+        ** original old.* record, and the other values from the original
+        ** new.* record. */
+        for(iCol=0; iCol<nCol; iCol++){
+          sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];
+          sessionAppendValue(&sOut, pVal, &rc);
+        }
+
+        /* Write the new new.* record. Consists of a copy of all values
+        ** from the original old.* record, except for the PK columns, which
+        ** are set to "undefined". */
+        for(iCol=0; iCol<nCol; iCol++){
+          sqlite3_value *pVal = (abPK[iCol] ? 0 : apVal[iCol]);
+          sessionAppendValue(&sOut, pVal, &rc);
+        }
+
+        for(iCol=0; iCol<nCol*2; iCol++){
+          sqlite3ValueFree(apVal[iCol]);
+        }
+        memset(apVal, 0, sizeof(apVal[0])*nCol*2);
+        if( rc!=SQLITE_OK ){
+          goto finished_invert;
+        }
+
+        break;
+      }
+
+      default:
+        rc = SQLITE_CORRUPT_BKPT;
+        goto finished_invert;
+    }
+
+    assert( rc==SQLITE_OK );
+    if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
+      rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+      sOut.nBuf = 0;
+      if( rc!=SQLITE_OK ) goto finished_invert;
+    }
+  }
+
+  assert( rc==SQLITE_OK );
+  if( pnInverted ){
+    *pnInverted = sOut.nBuf;
+    *ppInverted = sOut.aBuf;
+    sOut.aBuf = 0;
+  }else if( sOut.nBuf>0 ){
+    rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+  }
+
+ finished_invert:
+  sqlite3_free(sOut.aBuf);
+  sqlite3_free(apVal);
+  sqlite3_free(sPK.aBuf);
+  return rc;
+}
+
+
+/*
+** Invert a changeset object.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_invert(
+  int nChangeset,                 /* Number of bytes in input */
+  const void *pChangeset,         /* Input changeset */
+  int *pnInverted,                /* OUT: Number of bytes in output changeset */
+  void **ppInverted               /* OUT: Inverse of pChangeset */
+){
+  SessionInput sInput;
+
+  /* Set up the input stream */
+  memset(&sInput, 0, sizeof(SessionInput));
+  sInput.nData = nChangeset;
+  sInput.aData = (u8*)pChangeset;
+
+  return sessionChangesetInvert(&sInput, 0, 0, pnInverted, ppInverted);
+}
+
+/*
+** Streaming version of sqlite3changeset_invert().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_invert_strm(
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+){
+  SessionInput sInput;
+  int rc;
+
+  /* Set up the input stream */
+  memset(&sInput, 0, sizeof(SessionInput));
+  sInput.xInput = xInput;
+  sInput.pIn = pIn;
+
+  rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
+  sqlite3_free(sInput.buf.aBuf);
+  return rc;
+}
+
+typedef struct SessionApplyCtx SessionApplyCtx;
+struct SessionApplyCtx {
+  sqlite3 *db;
+  sqlite3_stmt *pDelete;          /* DELETE statement */
+  sqlite3_stmt *pUpdate;          /* UPDATE statement */
+  sqlite3_stmt *pInsert;          /* INSERT statement */
+  sqlite3_stmt *pSelect;          /* SELECT statement */
+  int nCol;                       /* Size of azCol[] and abPK[] arrays */
+  const char **azCol;             /* Array of column names */
+  u8 *abPK;                       /* Boolean array - true if column is in PK */
+
+  int bDeferConstraints;          /* True to defer constraints */
+  SessionBuffer constraints;      /* Deferred constraints are stored here */
+};
+
+/*
+** Formulate a statement to DELETE a row from database db. Assuming a table
+** structure like this:
+**
+**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
+**
+** The DELETE statement looks like this:
+**
+**     DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
+**
+** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
+** matching b and d values, or 1 otherwise. The second case comes up if the
+** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
+**
+** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
+** pointing to the prepared version of the SQL statement.
+*/
+static int sessionDeleteRow(
+  sqlite3 *db,                    /* Database handle */
+  const char *zTab,               /* Table name */
+  SessionApplyCtx *p              /* Session changeset-apply context */
+){
+  int i;
+  const char *zSep = "";
+  int rc = SQLITE_OK;
+  SessionBuffer buf = {0, 0, 0};
+  int nPk = 0;
+
+  sessionAppendStr(&buf, "DELETE FROM ", &rc);
+  sessionAppendIdent(&buf, zTab, &rc);
+  sessionAppendStr(&buf, " WHERE ", &rc);
+
+  for(i=0; i<p->nCol; i++){
+    if( p->abPK[i] ){
+      nPk++;
+      sessionAppendStr(&buf, zSep, &rc);
+      sessionAppendIdent(&buf, p->azCol[i], &rc);
+      sessionAppendStr(&buf, " = ?", &rc);
+      sessionAppendInteger(&buf, i+1, &rc);
+      zSep = " AND ";
+    }
+  }
+
+  if( nPk<p->nCol ){
+    sessionAppendStr(&buf, " AND (?", &rc);
+    sessionAppendInteger(&buf, p->nCol+1, &rc);
+    sessionAppendStr(&buf, " OR ", &rc);
+
+    zSep = "";
+    for(i=0; i<p->nCol; i++){
+      if( !p->abPK[i] ){
+        sessionAppendStr(&buf, zSep, &rc);
+        sessionAppendIdent(&buf, p->azCol[i], &rc);
+        sessionAppendStr(&buf, " IS ?", &rc);
+        sessionAppendInteger(&buf, i+1, &rc);
+        zSep = "AND ";
+      }
+    }
+    sessionAppendStr(&buf, ")", &rc);
+  }
+
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
+  }
+  sqlite3_free(buf.aBuf);
+
+  return rc;
+}
+
+/*
+** Formulate and prepare a statement to UPDATE a row from database db. 
+** Assuming a table structure like this:
+**
+**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
+**
+** The UPDATE statement looks like this:
+**
+**     UPDATE x SET
+**     a = CASE WHEN ?2  THEN ?3  ELSE a END,
+**     b = CASE WHEN ?5  THEN ?6  ELSE b END,
+**     c = CASE WHEN ?8  THEN ?9  ELSE c END,
+**     d = CASE WHEN ?11 THEN ?12 ELSE d END
+**     WHERE a = ?1 AND c = ?7 AND (?13 OR 
+**       (?5==0 OR b IS ?4) AND (?11==0 OR d IS ?10) AND
+**     )
+**
+** For each column in the table, there are three variables to bind:
+**
+**     ?(i*3+1)    The old.* value of the column, if any.
+**     ?(i*3+2)    A boolean flag indicating that the value is being modified.
+**     ?(i*3+3)    The new.* value of the column, if any.
+**
+** Also, a boolean flag that, if set to true, causes the statement to update
+** a row even if the non-PK values do not match. This is required if the
+** conflict-handler is invoked with CHANGESET_DATA and returns
+** CHANGESET_REPLACE. This is variable "?(nCol*3+1)".
+**
+** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left
+** pointing to the prepared version of the SQL statement.
+*/
+static int sessionUpdateRow(
+  sqlite3 *db,                    /* Database handle */
+  const char *zTab,               /* Table name */
+  SessionApplyCtx *p              /* Session changeset-apply context */
+){
+  int rc = SQLITE_OK;
+  int i;
+  const char *zSep = "";
+  SessionBuffer buf = {0, 0, 0};
+
+  /* Append "UPDATE tbl SET " */
+  sessionAppendStr(&buf, "UPDATE ", &rc);
+  sessionAppendIdent(&buf, zTab, &rc);
+  sessionAppendStr(&buf, " SET ", &rc);
+
+  /* Append the assignments */
+  for(i=0; i<p->nCol; i++){
+    sessionAppendStr(&buf, zSep, &rc);
+    sessionAppendIdent(&buf, p->azCol[i], &rc);
+    sessionAppendStr(&buf, " = CASE WHEN ?", &rc);
+    sessionAppendInteger(&buf, i*3+2, &rc);
+    sessionAppendStr(&buf, " THEN ?", &rc);
+    sessionAppendInteger(&buf, i*3+3, &rc);
+    sessionAppendStr(&buf, " ELSE ", &rc);
+    sessionAppendIdent(&buf, p->azCol[i], &rc);
+    sessionAppendStr(&buf, " END", &rc);
+    zSep = ", ";
+  }
+
+  /* Append the PK part of the WHERE clause */
+  sessionAppendStr(&buf, " WHERE ", &rc);
+  for(i=0; i<p->nCol; i++){
+    if( p->abPK[i] ){
+      sessionAppendIdent(&buf, p->azCol[i], &rc);
+      sessionAppendStr(&buf, " = ?", &rc);
+      sessionAppendInteger(&buf, i*3+1, &rc);
+      sessionAppendStr(&buf, " AND ", &rc);
+    }
+  }
+
+  /* Append the non-PK part of the WHERE clause */
+  sessionAppendStr(&buf, " (?", &rc);
+  sessionAppendInteger(&buf, p->nCol*3+1, &rc);
+  sessionAppendStr(&buf, " OR 1", &rc);
+  for(i=0; i<p->nCol; i++){
+    if( !p->abPK[i] ){
+      sessionAppendStr(&buf, " AND (?", &rc);
+      sessionAppendInteger(&buf, i*3+2, &rc);
+      sessionAppendStr(&buf, "=0 OR ", &rc);
+      sessionAppendIdent(&buf, p->azCol[i], &rc);
+      sessionAppendStr(&buf, " IS ?", &rc);
+      sessionAppendInteger(&buf, i*3+1, &rc);
+      sessionAppendStr(&buf, ")", &rc);
+    }
+  }
+  sessionAppendStr(&buf, ")", &rc);
+
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0);
+  }
+  sqlite3_free(buf.aBuf);
+
+  return rc;
+}
+
+/*
+** Formulate and prepare an SQL statement to query table zTab by primary
+** key. Assuming the following table structure:
+**
+**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
+**
+** The SELECT statement looks like this:
+**
+**     SELECT * FROM x WHERE a = ?1 AND c = ?3
+**
+** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
+** pointing to the prepared version of the SQL statement.
+*/
+static int sessionSelectRow(
+  sqlite3 *db,                    /* Database handle */
+  const char *zTab,               /* Table name */
+  SessionApplyCtx *p              /* Session changeset-apply context */
+){
+  return sessionSelectStmt(
+      db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect);
+}
+
+/*
+** Formulate and prepare an INSERT statement to add a record to table zTab.
+** For example:
+**
+**     INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
+**
+** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
+** pointing to the prepared version of the SQL statement.
+*/
+static int sessionInsertRow(
+  sqlite3 *db,                    /* Database handle */
+  const char *zTab,               /* Table name */
+  SessionApplyCtx *p              /* Session changeset-apply context */
+){
+  int rc = SQLITE_OK;
+  int i;
+  SessionBuffer buf = {0, 0, 0};
+
+  sessionAppendStr(&buf, "INSERT INTO main.", &rc);
+  sessionAppendIdent(&buf, zTab, &rc);
+  sessionAppendStr(&buf, " VALUES(?", &rc);
+  for(i=1; i<p->nCol; i++){
+    sessionAppendStr(&buf, ", ?", &rc);
+  }
+  sessionAppendStr(&buf, ")", &rc);
+
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
+  }
+  sqlite3_free(buf.aBuf);
+  return rc;
+}
+
+/*
+** A wrapper around sqlite3_bind_value() that detects an extra problem. 
+** See comments in the body of this function for details.
+*/
+static int sessionBindValue(
+  sqlite3_stmt *pStmt,            /* Statement to bind value to */
+  int i,                          /* Parameter number to bind to */
+  sqlite3_value *pVal             /* Value to bind */
+){
+  int eType = sqlite3_value_type(pVal);
+  /* COVERAGE: The (pVal->z==0) branch is never true using current versions
+  ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either
+  ** the (pVal->z) variable remains as it was or the type of the value is
+  ** set to SQLITE_NULL.  */
+  if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){
+    /* This condition occurs when an earlier OOM in a call to
+    ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within
+    ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */
+    return SQLITE_NOMEM;
+  }
+  return sqlite3_bind_value(pStmt, i, pVal);
+}
+
+/*
+** Iterator pIter must point to an SQLITE_INSERT entry. This function 
+** transfers new.* values from the current iterator entry to statement
+** pStmt. The table being inserted into has nCol columns.
+**
+** New.* value $i from the iterator is bound to variable ($i+1) of 
+** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
+** are transfered to the statement. Otherwise, if abPK is not NULL, it points
+** to an array nCol elements in size. In this case only those values for 
+** which abPK[$i] is true are read from the iterator and bound to the 
+** statement.
+**
+** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
+*/
+static int sessionBindRow(
+  sqlite3_changeset_iter *pIter,  /* Iterator to read values from */
+  int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
+  int nCol,                       /* Number of columns */
+  u8 *abPK,                       /* If not NULL, bind only if true */
+  sqlite3_stmt *pStmt             /* Bind values to this statement */
+){
+  int i;
+  int rc = SQLITE_OK;
+
+  /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the
+  ** argument iterator points to a suitable entry. Make sure that xValue 
+  ** is one of these to guarantee that it is safe to ignore the return 
+  ** in the code below. */
+  assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
+
+  for(i=0; rc==SQLITE_OK && i<nCol; i++){
+    if( !abPK || abPK[i] ){
+      sqlite3_value *pVal;
+      (void)xValue(pIter, i, &pVal);
+      rc = sessionBindValue(pStmt, i+1, pVal);
+    }
+  }
+  return rc;
+}
+
+/*
+** SQL statement pSelect is as generated by the sessionSelectRow() function.
+** This function binds the primary key values from the change that changeset
+** iterator pIter points to to the SELECT and attempts to seek to the table
+** entry. If a row is found, the SELECT statement left pointing at the row 
+** and SQLITE_ROW is returned. Otherwise, if no row is found and no error
+** has occured, the statement is reset and SQLITE_OK is returned. If an
+** error occurs, the statement is reset and an SQLite error code is returned.
+**
+** If this function returns SQLITE_ROW, the caller must eventually reset() 
+** statement pSelect. If any other value is returned, the statement does
+** not require a reset().
+**
+** If the iterator currently points to an INSERT record, bind values from the
+** new.* record to the SELECT statement. Or, if it points to a DELETE or
+** UPDATE, bind values from the old.* record. 
+*/
+static int sessionSeekToRow(
+  sqlite3 *db,                    /* Database handle */
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  u8 *abPK,                       /* Primary key flags array */
+  sqlite3_stmt *pSelect           /* SELECT statement from sessionSelectRow() */
+){
+  int rc;                         /* Return code */
+  int nCol;                       /* Number of columns in table */
+  int op;                         /* Changset operation (SQLITE_UPDATE etc.) */
+  const char *zDummy;             /* Unused */
+
+  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
+  rc = sessionBindRow(pIter, 
+      op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
+      nCol, abPK, pSelect
+  );
+
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_step(pSelect);
+    if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
+  }
+
+  return rc;
+}
+
+/*
+** Invoke the conflict handler for the change that the changeset iterator
+** currently points to.
+**
+** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT.
+** If argument pbReplace is NULL, then the type of conflict handler invoked
+** depends solely on eType, as follows:
+**
+**    eType value                 Value passed to xConflict
+**    -------------------------------------------------
+**    CHANGESET_DATA              CHANGESET_NOTFOUND
+**    CHANGESET_CONFLICT          CHANGESET_CONSTRAINT
+**
+** Or, if pbReplace is not NULL, then an attempt is made to find an existing
+** record with the same primary key as the record about to be deleted, updated
+** or inserted. If such a record can be found, it is available to the conflict
+** handler as the "conflicting" record. In this case the type of conflict
+** handler invoked is as follows:
+**
+**    eType value         PK Record found?   Value passed to xConflict
+**    ----------------------------------------------------------------
+**    CHANGESET_DATA      Yes                CHANGESET_DATA
+**    CHANGESET_DATA      No                 CHANGESET_NOTFOUND
+**    CHANGESET_CONFLICT  Yes                CHANGESET_CONFLICT
+**    CHANGESET_CONFLICT  No                 CHANGESET_CONSTRAINT
+**
+** If pbReplace is not NULL, and a record with a matching PK is found, and
+** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace
+** is set to non-zero before returning SQLITE_OK.
+**
+** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is
+** returned. Or, if the conflict handler returns an invalid value, 
+** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT,
+** this function returns SQLITE_OK.
+*/
+static int sessionConflictHandler(
+  int eType,                      /* Either CHANGESET_DATA or CONFLICT */
+  SessionApplyCtx *p,             /* changeset_apply() context */
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int(*xConflict)(void *, int, sqlite3_changeset_iter*),
+  void *pCtx,                     /* First argument for conflict handler */
+  int *pbReplace                  /* OUT: Set to true if PK row is found */
+){
+  int res = 0;                    /* Value returned by conflict handler */
+  int rc;
+  int nCol;
+  int op;
+  const char *zDummy;
+
+  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
+
+  assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA );
+  assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT );
+  assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND );
+
+  /* Bind the new.* PRIMARY KEY values to the SELECT statement. */
+  if( pbReplace ){
+    rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+  }else{
+    rc = SQLITE_OK;
+  }
+
+  if( rc==SQLITE_ROW ){
+    /* There exists another row with the new.* primary key. */
+    pIter->pConflict = p->pSelect;
+    res = xConflict(pCtx, eType, pIter);
+    pIter->pConflict = 0;
+    rc = sqlite3_reset(p->pSelect);
+  }else if( rc==SQLITE_OK ){
+    if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){
+      /* Instead of invoking the conflict handler, append the change blob
+      ** to the SessionApplyCtx.constraints buffer. */
+      u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
+      int nBlob = pIter->in.iNext - pIter->in.iCurrent;
+      sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
+      res = SQLITE_CHANGESET_OMIT;
+    }else{
+      /* No other row with the new.* primary key. */
+      res = xConflict(pCtx, eType+1, pIter);
+      if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
+    }
+  }
+
+  if( rc==SQLITE_OK ){
+    switch( res ){
+      case SQLITE_CHANGESET_REPLACE:
+        assert( pbReplace );
+        *pbReplace = 1;
+        break;
+
+      case SQLITE_CHANGESET_OMIT:
+        break;
+
+      case SQLITE_CHANGESET_ABORT:
+        rc = SQLITE_ABORT;
+        break;
+
+      default:
+        rc = SQLITE_MISUSE;
+        break;
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Attempt to apply the change that the iterator passed as the first argument
+** currently points to to the database. If a conflict is encountered, invoke
+** the conflict handler callback.
+**
+** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If
+** one is encountered, update or delete the row with the matching primary key
+** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs,
+** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry
+** to true before returning. In this case the caller will invoke this function
+** again, this time with pbRetry set to NULL.
+**
+** If argument pbReplace is NULL and a CHANGESET_CONFLICT conflict is 
+** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead.
+** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such
+** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true
+** before retrying. In this case the caller attempts to remove the conflicting
+** row before invoking this function again, this time with pbReplace set 
+** to NULL.
+**
+** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function
+** returns SQLITE_ABORT. Otherwise, if no error occurs, SQLITE_OK is 
+** returned.
+*/
+static int sessionApplyOneOp(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  SessionApplyCtx *p,             /* changeset_apply() context */
+  int(*xConflict)(void *, int, sqlite3_changeset_iter *),
+  void *pCtx,                     /* First argument for the conflict handler */
+  int *pbReplace,                 /* OUT: True to remove PK row and retry */
+  int *pbRetry                    /* OUT: True to retry. */
+){
+  const char *zDummy;
+  int op;
+  int nCol;
+  int rc = SQLITE_OK;
+
+  assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect );
+  assert( p->azCol && p->abPK );
+  assert( !pbReplace || *pbReplace==0 );
+
+  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
+
+  if( op==SQLITE_DELETE ){
+
+    /* Bind values to the DELETE statement. If conflict handling is required,
+    ** bind values for all columns and set bound variable (nCol+1) to true.
+    ** Or, if conflict handling is not required, bind just the PK column
+    ** values and, if it exists, set (nCol+1) to false. Conflict handling
+    ** is not required if:
+    **
+    **   * this is a patchset, or
+    **   * (pbRetry==0), or
+    **   * all columns of the table are PK columns (in this case there is
+    **     no (nCol+1) variable to bind to).
+    */
+    u8 *abPK = (pIter->bPatchset ? p->abPK : 0);
+    rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete);
+    if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
+      rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK));
+    }
+    if( rc!=SQLITE_OK ) return rc;
+
+    sqlite3_step(p->pDelete);
+    rc = sqlite3_reset(p->pDelete);
+    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
+      rc = sessionConflictHandler(
+          SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
+      );
+    }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
+      rc = sessionConflictHandler(
+          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
+      );
+    }
+
+  }else if( op==SQLITE_UPDATE ){
+    int i;
+
+    /* Bind values to the UPDATE statement. */
+    for(i=0; rc==SQLITE_OK && i<nCol; i++){
+      sqlite3_value *pOld = sessionChangesetOld(pIter, i);
+      sqlite3_value *pNew = sessionChangesetNew(pIter, i);
+
+      sqlite3_bind_int(p->pUpdate, i*3+2, !!pNew);
+      if( pOld ){
+        rc = sessionBindValue(p->pUpdate, i*3+1, pOld);
+      }
+      if( rc==SQLITE_OK && pNew ){
+        rc = sessionBindValue(p->pUpdate, i*3+3, pNew);
+      }
+    }
+    if( rc==SQLITE_OK ){
+      sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset);
+    }
+    if( rc!=SQLITE_OK ) return rc;
+
+    /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
+    ** the result will be SQLITE_OK with 0 rows modified. */
+    sqlite3_step(p->pUpdate);
+    rc = sqlite3_reset(p->pUpdate);
+
+    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
+      /* A NOTFOUND or DATA error. Search the table to see if it contains
+      ** a row with a matching primary key. If so, this is a DATA conflict.
+      ** Otherwise, if there is no primary key match, it is a NOTFOUND. */
+
+      rc = sessionConflictHandler(
+          SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
+      );
+
+    }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
+      /* This is always a CONSTRAINT conflict. */
+      rc = sessionConflictHandler(
+          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
+      );
+    }
+
+  }else{
+    assert( op==SQLITE_INSERT );
+    rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
+    if( rc!=SQLITE_OK ) return rc;
+
+    sqlite3_step(p->pInsert);
+    rc = sqlite3_reset(p->pInsert);
+    if( (rc&0xff)==SQLITE_CONSTRAINT ){
+      rc = sessionConflictHandler(
+          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
+      );
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Attempt to apply the change that the iterator passed as the first argument
+** currently points to to the database. If a conflict is encountered, invoke
+** the conflict handler callback.
+**
+** The difference between this function and sessionApplyOne() is that this
+** function handles the case where the conflict-handler is invoked and 
+** returns SQLITE_CHANGESET_REPLACE - indicating that the change should be
+** retried in some manner.
+*/
+static int sessionApplyOneWithRetry(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator to read change from */
+  SessionApplyCtx *pApply,        /* Apply context */
+  int(*xConflict)(void*, int, sqlite3_changeset_iter*),
+  void *pCtx                      /* First argument passed to xConflict */
+){
+  int bReplace = 0;
+  int bRetry = 0;
+  int rc;
+
+  rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
+  assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) );
+
+  /* If the bRetry flag is set, the change has not been applied due to an
+  ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
+  ** a row with the correct PK is present in the db, but one or more other
+  ** fields do not contain the expected values) and the conflict handler 
+  ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
+  ** but pass NULL as the final argument so that sessionApplyOneOp() ignores
+  ** the SQLITE_CHANGESET_DATA problem.  */
+  if( bRetry ){
+    assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
+    rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
+  }
+
+  /* If the bReplace flag is set, the change is an INSERT that has not
+  ** been performed because the database already contains a row with the
+  ** specified primary key and the conflict handler returned
+  ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
+  ** before reattempting the INSERT.  */
+  else if( bReplace ){
+    assert( pIter->op==SQLITE_INSERT );
+    rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
+    if( rc==SQLITE_OK ){
+      rc = sessionBindRow(pIter, 
+          sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
+      sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
+    }
+    if( rc==SQLITE_OK ){
+      sqlite3_step(pApply->pDelete);
+      rc = sqlite3_reset(pApply->pDelete);
+    }
+    if( rc==SQLITE_OK ){
+      rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
+    }
+    if( rc==SQLITE_OK ){
+      rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Retry the changes accumulated in the pApply->constraints buffer.
+*/
+static int sessionRetryConstraints(
+  sqlite3 *db, 
+  int bPatchset,
+  const char *zTab,
+  SessionApplyCtx *pApply,
+  int(*xConflict)(void*, int, sqlite3_changeset_iter*),
+  void *pCtx                      /* First argument passed to xConflict */
+){
+  int rc = SQLITE_OK;
+
+  while( pApply->constraints.nBuf ){
+    sqlite3_changeset_iter *pIter2 = 0;
+    SessionBuffer cons = pApply->constraints;
+    memset(&pApply->constraints, 0, sizeof(SessionBuffer));
+
+    rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
+    if( rc==SQLITE_OK ){
+      int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
+      int rc2;
+      pIter2->bPatchset = bPatchset;
+      pIter2->zTab = (char*)zTab;
+      pIter2->nCol = pApply->nCol;
+      pIter2->abPK = pApply->abPK;
+      sessionBufferGrow(&pIter2->tblhdr, nByte, &rc);
+      pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf;
+      if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte);
+
+      while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){
+        rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx);
+      }
+
+      rc2 = sqlite3changeset_finalize(pIter2);
+      if( rc==SQLITE_OK ) rc = rc2;
+    }
+    assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
+
+    sqlite3_free(cons.aBuf);
+    if( rc!=SQLITE_OK ) break;
+    if( pApply->constraints.nBuf>=cons.nBuf ){
+      /* No progress was made on the last round. */
+      pApply->bDeferConstraints = 0;
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Argument pIter is a changeset iterator that has been initialized, but
+** not yet passed to sqlite3changeset_next(). This function applies the 
+** changeset to the main database attached to handle "db". The supplied
+** conflict handler callback is invoked to resolve any conflicts encountered
+** while applying the change.
+*/
+static int sessionChangesetApply(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  sqlite3_changeset_iter *pIter,  /* Changeset to apply */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of fifth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+){
+  int schemaMismatch = 0;
+  int rc;                         /* Return code */
+  const char *zTab = 0;           /* Name of current table */
+  int nTab = 0;                   /* Result of sqlite3Strlen30(zTab) */
+  SessionApplyCtx sApply;         /* changeset_apply() context object */
+  int bPatchset;
+
+  assert( xConflict!=0 );
+
+  pIter->in.bNoDiscard = 1;
+  memset(&sApply, 0, sizeof(sApply));
+  sqlite3_mutex_enter(sqlite3_db_mutex(db));
+  rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
+  }
+  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
+    int nCol;
+    int op;
+    const char *zNew;
+    
+    sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0);
+
+    if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){
+      u8 *abPK;
+
+      rc = sessionRetryConstraints(
+          db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
+      );
+      if( rc!=SQLITE_OK ) break;
+
+      sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
+      sqlite3_finalize(sApply.pDelete);
+      sqlite3_finalize(sApply.pUpdate); 
+      sqlite3_finalize(sApply.pInsert);
+      sqlite3_finalize(sApply.pSelect);
+      memset(&sApply, 0, sizeof(sApply));
+      sApply.db = db;
+      sApply.bDeferConstraints = 1;
+
+      /* If an xFilter() callback was specified, invoke it now. If the 
+      ** xFilter callback returns zero, skip this table. If it returns
+      ** non-zero, proceed. */
+      schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew)));
+      if( schemaMismatch ){
+        zTab = sqlite3_mprintf("%s", zNew);
+        if( zTab==0 ){
+          rc = SQLITE_NOMEM;
+          break;
+        }
+        nTab = (int)strlen(zTab);
+        sApply.azCol = (const char **)zTab;
+      }else{
+        sqlite3changeset_pk(pIter, &abPK, 0);
+        rc = sessionTableInfo(
+            db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
+        );
+        if( rc!=SQLITE_OK ) break;
+  
+        if( sApply.nCol==0 ){
+          schemaMismatch = 1;
+          sqlite3_log(SQLITE_SCHEMA, 
+              "sqlite3changeset_apply(): no such table: %s", zTab
+          );
+        }
+        else if( sApply.nCol!=nCol ){
+          schemaMismatch = 1;
+          sqlite3_log(SQLITE_SCHEMA, 
+              "sqlite3changeset_apply(): table %s has %d columns, expected %d", 
+              zTab, sApply.nCol, nCol
+          );
+        }
+        else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){
+          schemaMismatch = 1;
+          sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
+              "primary key mismatch for table %s", zTab
+          );
+        }
+        else if( 
+            (rc = sessionSelectRow(db, zTab, &sApply))
+         || (rc = sessionUpdateRow(db, zTab, &sApply))
+         || (rc = sessionDeleteRow(db, zTab, &sApply))
+         || (rc = sessionInsertRow(db, zTab, &sApply))
+        ){
+          break;
+        }
+        nTab = sqlite3Strlen30(zTab);
+      }
+    }
+
+    /* If there is a schema mismatch on the current table, proceed to the
+    ** next change. A log message has already been issued. */
+    if( schemaMismatch ) continue;
+
+    rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
+  }
+
+  bPatchset = pIter->bPatchset;
+  if( rc==SQLITE_OK ){
+    rc = sqlite3changeset_finalize(pIter);
+  }else{
+    sqlite3changeset_finalize(pIter);
+  }
+
+  if( rc==SQLITE_OK ){
+    rc = sessionRetryConstraints(db, bPatchset, zTab, &sApply, xConflict, pCtx);
+  }
+
+  if( rc==SQLITE_OK ){
+    int nFk, notUsed;
+    sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, &notUsed, 0);
+    if( nFk!=0 ){
+      int res = SQLITE_CHANGESET_ABORT;
+      sqlite3_changeset_iter sIter;
+      memset(&sIter, 0, sizeof(sIter));
+      sIter.nCol = nFk;
+      res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
+      if( res!=SQLITE_CHANGESET_OMIT ){
+        rc = SQLITE_CONSTRAINT;
+      }
+    }
+  }
+  sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
+
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
+  }else{
+    sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
+    sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
+  }
+
+  sqlite3_finalize(sApply.pInsert);
+  sqlite3_finalize(sApply.pDelete);
+  sqlite3_finalize(sApply.pUpdate);
+  sqlite3_finalize(sApply.pSelect);
+  sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
+  sqlite3_free((char*)sApply.constraints.aBuf);
+  sqlite3_mutex_leave(sqlite3_db_mutex(db));
+  return rc;
+}
+
+/*
+** Apply the changeset passed via pChangeset/nChangeset to the main database
+** attached to handle "db". Invoke the supplied conflict handler callback
+** to resolve any conflicts encountered while applying the change.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_apply(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int nChangeset,                 /* Size of changeset in bytes */
+  void *pChangeset,               /* Changeset blob */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of fifth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+){
+  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
+  int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
+  if( rc==SQLITE_OK ){
+    rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
+  }
+  return rc;
+}
+
+/*
+** Apply the changeset passed via xInput/pIn to the main database
+** attached to handle "db". Invoke the supplied conflict handler callback
+** to resolve any conflicts encountered while applying the change.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_apply_strm(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+  void *pIn,                                          /* First arg for xInput */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+){
+  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
+  int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
+  if( rc==SQLITE_OK ){
+    rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
+  }
+  return rc;
+}
+
+/*
+** sqlite3_changegroup handle.
+*/
+struct sqlite3_changegroup {
+  int rc;                         /* Error code */
+  int bPatch;                     /* True to accumulate patchsets */
+  SessionTable *pList;            /* List of tables in current patch */
+};
+
+/*
+** This function is called to merge two changes to the same row together as
+** part of an sqlite3changeset_concat() operation. A new change object is
+** allocated and a pointer to it stored in *ppNew.
+*/
+static int sessionChangeMerge(
+  SessionTable *pTab,             /* Table structure */
+  int bPatchset,                  /* True for patchsets */
+  SessionChange *pExist,          /* Existing change */
+  int op2,                        /* Second change operation */
+  int bIndirect,                  /* True if second change is indirect */
+  u8 *aRec,                       /* Second change record */
+  int nRec,                       /* Number of bytes in aRec */
+  SessionChange **ppNew           /* OUT: Merged change */
+){
+  SessionChange *pNew = 0;
+
+  if( !pExist ){
+    pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec);
+    if( !pNew ){
+      return SQLITE_NOMEM;
+    }
+    memset(pNew, 0, sizeof(SessionChange));
+    pNew->op = op2;
+    pNew->bIndirect = bIndirect;
+    pNew->nRecord = nRec;
+    pNew->aRecord = (u8*)&pNew[1];
+    memcpy(pNew->aRecord, aRec, nRec);
+  }else{
+    int op1 = pExist->op;
+
+    /* 
+    **   op1=INSERT, op2=INSERT      ->      Unsupported. Discard op2.
+    **   op1=INSERT, op2=UPDATE      ->      INSERT.
+    **   op1=INSERT, op2=DELETE      ->      (none)
+    **
+    **   op1=UPDATE, op2=INSERT      ->      Unsupported. Discard op2.
+    **   op1=UPDATE, op2=UPDATE      ->      UPDATE.
+    **   op1=UPDATE, op2=DELETE      ->      DELETE.
+    **
+    **   op1=DELETE, op2=INSERT      ->      UPDATE.
+    **   op1=DELETE, op2=UPDATE      ->      Unsupported. Discard op2.
+    **   op1=DELETE, op2=DELETE      ->      Unsupported. Discard op2.
+    */   
+    if( (op1==SQLITE_INSERT && op2==SQLITE_INSERT)
+     || (op1==SQLITE_UPDATE && op2==SQLITE_INSERT)
+     || (op1==SQLITE_DELETE && op2==SQLITE_UPDATE)
+     || (op1==SQLITE_DELETE && op2==SQLITE_DELETE)
+    ){
+      pNew = pExist;
+    }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){
+      sqlite3_free(pExist);
+      assert( pNew==0 );
+    }else{
+      u8 *aExist = pExist->aRecord;
+      int nByte;
+      u8 *aCsr;
+
+      /* Allocate a new SessionChange object. Ensure that the aRecord[]
+      ** buffer of the new object is large enough to hold any record that
+      ** may be generated by combining the input records.  */
+      nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
+      pNew = (SessionChange *)sqlite3_malloc(nByte);
+      if( !pNew ){
+        sqlite3_free(pExist);
+        return SQLITE_NOMEM;
+      }
+      memset(pNew, 0, sizeof(SessionChange));
+      pNew->bIndirect = (bIndirect && pExist->bIndirect);
+      aCsr = pNew->aRecord = (u8 *)&pNew[1];
+
+      if( op1==SQLITE_INSERT ){             /* INSERT + UPDATE */
+        u8 *a1 = aRec;
+        assert( op2==SQLITE_UPDATE );
+        pNew->op = SQLITE_INSERT;
+        if( bPatchset==0 ) sessionSkipRecord(&a1, pTab->nCol);
+        sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1);
+      }else if( op1==SQLITE_DELETE ){       /* DELETE + INSERT */
+        assert( op2==SQLITE_INSERT );
+        pNew->op = SQLITE_UPDATE;
+        if( bPatchset ){
+          memcpy(aCsr, aRec, nRec);
+          aCsr += nRec;
+        }else{
+          if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){
+            sqlite3_free(pNew);
+            pNew = 0;
+          }
+        }
+      }else if( op2==SQLITE_UPDATE ){       /* UPDATE + UPDATE */
+        u8 *a1 = aExist;
+        u8 *a2 = aRec;
+        assert( op1==SQLITE_UPDATE );
+        if( bPatchset==0 ){
+          sessionSkipRecord(&a1, pTab->nCol);
+          sessionSkipRecord(&a2, pTab->nCol);
+        }
+        pNew->op = SQLITE_UPDATE;
+        if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){
+          sqlite3_free(pNew);
+          pNew = 0;
+        }
+      }else{                                /* UPDATE + DELETE */
+        assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE );
+        pNew->op = SQLITE_DELETE;
+        if( bPatchset ){
+          memcpy(aCsr, aRec, nRec);
+          aCsr += nRec;
+        }else{
+          sessionMergeRecord(&aCsr, pTab->nCol, aRec, aExist);
+        }
+      }
+
+      if( pNew ){
+        pNew->nRecord = (int)(aCsr - pNew->aRecord);
+      }
+      sqlite3_free(pExist);
+    }
+  }
+
+  *ppNew = pNew;
+  return SQLITE_OK;
+}
+
+/*
+** Add all changes in the changeset traversed by the iterator passed as
+** the first argument to the changegroup hash tables.
+*/
+static int sessionChangesetToHash(
+  sqlite3_changeset_iter *pIter,   /* Iterator to read from */
+  sqlite3_changegroup *pGrp        /* Changegroup object to add changeset to */
+){
+  u8 *aRec;
+  int nRec;
+  int rc = SQLITE_OK;
+  SessionTable *pTab = 0;
+
+
+  while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){
+    const char *zNew;
+    int nCol;
+    int op;
+    int iHash;
+    int bIndirect;
+    SessionChange *pChange;
+    SessionChange *pExist = 0;
+    SessionChange **pp;
+
+    if( pGrp->pList==0 ){
+      pGrp->bPatch = pIter->bPatchset;
+    }else if( pIter->bPatchset!=pGrp->bPatch ){
+      rc = SQLITE_ERROR;
+      break;
+    }
+
+    sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect);
+    if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){
+      /* Search the list for a matching table */
+      int nNew = (int)strlen(zNew);
+      u8 *abPK;
+
+      sqlite3changeset_pk(pIter, &abPK, 0);
+      for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
+        if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break;
+      }
+      if( !pTab ){
+        SessionTable **ppTab;
+
+        pTab = sqlite3_malloc(sizeof(SessionTable) + nCol + nNew+1);
+        if( !pTab ){
+          rc = SQLITE_NOMEM;
+          break;
+        }
+        memset(pTab, 0, sizeof(SessionTable));
+        pTab->nCol = nCol;
+        pTab->abPK = (u8*)&pTab[1];
+        memcpy(pTab->abPK, abPK, nCol);
+        pTab->zName = (char*)&pTab->abPK[nCol];
+        memcpy(pTab->zName, zNew, nNew+1);
+
+        /* The new object must be linked on to the end of the list, not
+        ** simply added to the start of it. This is to ensure that the
+        ** tables within the output of sqlite3changegroup_output() are in 
+        ** the right order.  */
+        for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext);
+        *ppTab = pTab;
+      }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){
+        rc = SQLITE_SCHEMA;
+        break;
+      }
+    }
+
+    if( sessionGrowHash(pIter->bPatchset, pTab) ){
+      rc = SQLITE_NOMEM;
+      break;
+    }
+    iHash = sessionChangeHash(
+        pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
+    );
+
+    /* Search for existing entry. If found, remove it from the hash table. 
+    ** Code below may link it back in.
+    */
+    for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){
+      int bPkOnly1 = 0;
+      int bPkOnly2 = 0;
+      if( pIter->bPatchset ){
+        bPkOnly1 = (*pp)->op==SQLITE_DELETE;
+        bPkOnly2 = op==SQLITE_DELETE;
+      }
+      if( sessionChangeEqual(pTab, bPkOnly1, (*pp)->aRecord, bPkOnly2, aRec) ){
+        pExist = *pp;
+        *pp = (*pp)->pNext;
+        pTab->nEntry--;
+        break;
+      }
+    }
+
+    rc = sessionChangeMerge(pTab, 
+        pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
+    );
+    if( rc ) break;
+    if( pChange ){
+      pChange->pNext = pTab->apChange[iHash];
+      pTab->apChange[iHash] = pChange;
+      pTab->nEntry++;
+    }
+  }
+
+  if( rc==SQLITE_OK ) rc = pIter->rc;
+  return rc;
+}
+
+/*
+** Serialize a changeset (or patchset) based on all changesets (or patchsets)
+** added to the changegroup object passed as the first argument.
+**
+** If xOutput is not NULL, then the changeset/patchset is returned to the
+** user via one or more calls to xOutput, as with the other streaming
+** interfaces. 
+**
+** Or, if xOutput is NULL, then (*ppOut) is populated with a pointer to a
+** buffer containing the output changeset before this function returns. In
+** this case (*pnOut) is set to the size of the output buffer in bytes. It
+** is the responsibility of the caller to free the output buffer using
+** sqlite3_free() when it is no longer required.
+**
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite
+** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut)
+** are both set to 0 before returning.
+*/
+static int sessionChangegroupOutput(
+  sqlite3_changegroup *pGrp,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut,
+  int *pnOut,
+  void **ppOut
+){
+  int rc = SQLITE_OK;
+  SessionBuffer buf = {0, 0, 0};
+  SessionTable *pTab;
+  assert( xOutput==0 || (ppOut==0 && pnOut==0) );
+
+  /* Create the serialized output changeset based on the contents of the
+  ** hash tables attached to the SessionTable objects in list p->pList. 
+  */
+  for(pTab=pGrp->pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
+    int i;
+    if( pTab->nEntry==0 ) continue;
+
+    sessionAppendTableHdr(&buf, pGrp->bPatch, pTab, &rc);
+    for(i=0; i<pTab->nChange; i++){
+      SessionChange *p;
+      for(p=pTab->apChange[i]; p; p=p->pNext){
+        sessionAppendByte(&buf, p->op, &rc);
+        sessionAppendByte(&buf, p->bIndirect, &rc);
+        sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
+      }
+    }
+
+    if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
+      rc = xOutput(pOut, buf.aBuf, buf.nBuf);
+      buf.nBuf = 0;
+    }
+  }
+
+  if( rc==SQLITE_OK ){
+    if( xOutput ){
+      if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
+    }else{
+      *ppOut = buf.aBuf;
+      *pnOut = buf.nBuf;
+      buf.aBuf = 0;
+    }
+  }
+  sqlite3_free(buf.aBuf);
+
+  return rc;
+}
+
+/*
+** Allocate a new, empty, sqlite3_changegroup.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changegroup_new(sqlite3_changegroup **pp){
+  int rc = SQLITE_OK;             /* Return code */
+  sqlite3_changegroup *p;         /* New object */
+  p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup));
+  if( p==0 ){
+    rc = SQLITE_NOMEM;
+  }else{
+    memset(p, 0, sizeof(sqlite3_changegroup));
+  }
+  *pp = p;
+  return rc;
+}
+
+/*
+** Add the changeset currently stored in buffer pData, size nData bytes,
+** to changeset-group p.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
+  sqlite3_changeset_iter *pIter;  /* Iterator opened on pData/nData */
+  int rc;                         /* Return code */
+
+  rc = sqlite3changeset_start(&pIter, nData, pData);
+  if( rc==SQLITE_OK ){
+    rc = sessionChangesetToHash(pIter, pGrp);
+  }
+  sqlite3changeset_finalize(pIter);
+  return rc;
+}
+
+/*
+** Obtain a buffer containing a changeset representing the concatenation
+** of all changesets added to the group so far.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changegroup_output(
+    sqlite3_changegroup *pGrp,
+    int *pnData,
+    void **ppData
+){
+  return sessionChangegroupOutput(pGrp, 0, 0, pnData, ppData);
+}
+
+/*
+** Streaming versions of changegroup_add().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changegroup_add_strm(
+  sqlite3_changegroup *pGrp,
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn
+){
+  sqlite3_changeset_iter *pIter;  /* Iterator opened on pData/nData */
+  int rc;                         /* Return code */
+
+  rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
+  if( rc==SQLITE_OK ){
+    rc = sessionChangesetToHash(pIter, pGrp);
+  }
+  sqlite3changeset_finalize(pIter);
+  return rc;
+}
+
+/*
+** Streaming versions of changegroup_output().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changegroup_output_strm(
+  sqlite3_changegroup *pGrp,
+  int (*xOutput)(void *pOut, const void *pData, int nData), 
+  void *pOut
+){
+  return sessionChangegroupOutput(pGrp, xOutput, pOut, 0, 0);
+}
+
+/*
+** Delete a changegroup object.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
+  if( pGrp ){
+    sessionDeleteTable(pGrp->pList);
+    sqlite3_free(pGrp);
+  }
+}
+
+/* 
+** Combine two changesets together.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_concat(
+  int nLeft,                      /* Number of bytes in lhs input */
+  void *pLeft,                    /* Lhs input changeset */
+  int nRight                      /* Number of bytes in rhs input */,
+  void *pRight,                   /* Rhs input changeset */
+  int *pnOut,                     /* OUT: Number of bytes in output changeset */
+  void **ppOut                    /* OUT: changeset (left <concat> right) */
+){
+  sqlite3_changegroup *pGrp;
+  int rc;
+
+  rc = sqlite3changegroup_new(&pGrp);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3changegroup_add(pGrp, nLeft, pLeft);
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3changegroup_add(pGrp, nRight, pRight);
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
+  }
+  sqlite3changegroup_delete(pGrp);
+
+  return rc;
+}
+
+/*
+** Streaming version of sqlite3changeset_concat().
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3changeset_concat_strm(
+  int (*xInputA)(void *pIn, void *pData, int *pnData),
+  void *pInA,
+  int (*xInputB)(void *pIn, void *pData, int *pnData),
+  void *pInB,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+){
+  sqlite3_changegroup *pGrp;
+  int rc;
+
+  rc = sqlite3changegroup_new(&pGrp);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA);
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB);
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut);
+  }
+  sqlite3changegroup_delete(pGrp);
+
+  return rc;
+}
+
+#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
+
+/************** End of sqlite3session.c **************************************/
 /************** Begin file json1.c *******************************************/
 /*
 ** 2015-08-12
@@ -168296,11 +176577,13 @@ struct Fts5PhraseIter {
 **       ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
 **
 **   with $p set to a phrase equivalent to the phrase iPhrase of the
-**   current query is executed. For each row visited, the callback function
-**   passed as the fourth argument is invoked. The context and API objects 
-**   passed to the callback function may be used to access the properties of
-**   each matched row. Invoking Api.xUserData() returns a copy of the pointer
-**   passed as the third argument to pUserData.
+**   current query is executed. Any column filter that applies to
+**   phrase iPhrase of the current query is included in $p. For each 
+**   row visited, the callback function passed as the fourth argument 
+**   is invoked. The context and API objects passed to the callback 
+**   function may be used to access the properties of each matched row.
+**   Invoking Api.xUserData() returns a copy of the pointer passed as 
+**   the third argument to pUserData.
 **
 **   If the callback function returns any value other than SQLITE_OK, the
 **   query is abandoned and the xQueryPhrase function returns immediately.
@@ -168783,6 +177066,10 @@ typedef sqlite3_uint64 u64;
 
 #endif
 
+/* Truncate very long tokens to this many bytes. Hard limit is 
+** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
+** field that occurs at the start of each leaf page (see fts5_index.c). */
+#define FTS5_MAX_TOKEN_SIZE 32768
 
 /*
 ** Maximum number of prefix indexes on single FTS5 table. This must be
@@ -168908,6 +177195,7 @@ struct Fts5Config {
   int pgsz;                       /* Approximate page size used in %_data */
   int nAutomerge;                 /* 'automerge' setting */
   int nCrisisMerge;               /* Maximum allowed segments per level */
+  int nUsermerge;                 /* 'usermerge' setting */
   int nHashSize;                  /* Bytes of memory for in-memory hash */
   char *zRank;                    /* Name of rank function */
   char *zRankArgs;                /* Arguments to rank function */
@@ -168983,7 +177271,7 @@ static void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
 static void sqlite3Fts5BufferFree(Fts5Buffer*);
 static void sqlite3Fts5BufferZero(Fts5Buffer*);
 static void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*);
-static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
+static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, const char *zFmt, ...);
 
 static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
 
@@ -169215,6 +177503,7 @@ static int sqlite3Fts5IndexReads(Fts5Index *p);
 static int sqlite3Fts5IndexReinit(Fts5Index *p);
 static int sqlite3Fts5IndexOptimize(Fts5Index *p);
 static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
+static int sqlite3Fts5IndexReset(Fts5Index *p);
 
 static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
 
@@ -169357,6 +177646,7 @@ static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p);
 static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
 static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
 static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
+static int sqlite3Fts5StorageReset(Fts5Storage *p);
 
 /*
 ** End of interface to code in fts5_storage.c.
@@ -169436,6 +177726,12 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
   Fts5ExprNearset *pNear
 );
 
+static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
+  Fts5Parse *pParse,
+  Fts5ExprNode *pLeft,
+  Fts5ExprNode *pRight
+);
+
 static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
   Fts5Parse *pParse, 
   Fts5ExprPhrase *pPhrase, 
@@ -169668,10 +177964,6 @@ typedef union {
 #define fts5YY_NO_ACTION         90
 /************* End control #defines *******************************************/
 
-/* The fts5yyzerominor constant is used to initialize instances of
-** fts5YYMINORTYPE objects to zero. */
-static const fts5YYMINORTYPE fts5yyzerominor = { 0 };
-
 /* Define the fts5yytestcase() macro to be a no-op if is not already defined
 ** otherwise.
 **
@@ -169833,7 +178125,9 @@ struct fts5yyParser {
 #ifdef fts5YYTRACKMAXSTACKDEPTH
   int fts5yyidxMax;                 /* Maximum value of fts5yyidx */
 #endif
+#ifndef fts5YYNOERRORRECOVERY
   int fts5yyerrcnt;                 /* Shifts left before out of the error */
+#endif
   sqlite3Fts5ParserARG_SDECL                /* A place to hold %extra_argument */
 #if fts5YYSTACKDEPTH<=0
   int fts5yystksz;                  /* Current side of the stack */
@@ -170099,7 +178393,7 @@ static int sqlite3Fts5ParserStackPeak(void *p){
 ** Find the appropriate action for a parser given the terminal
 ** look-ahead token iLookAhead.
 */
-static int fts5yy_find_shift_action(
+static unsigned int fts5yy_find_shift_action(
   fts5yyParser *pParser,        /* The parser */
   fts5YYCODETYPE iLookAhead     /* The look-ahead token */
 ){
@@ -170195,7 +178489,7 @@ static int fts5yy_find_reduce_action(
 /*
 ** The following routine is called if the stack overflows.
 */
-static void fts5yyStackOverflow(fts5yyParser *fts5yypParser, fts5YYMINORTYPE *fts5yypMinor){
+static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
    sqlite3Fts5ParserARG_FETCH;
    fts5yypParser->fts5yyidx--;
 #ifndef NDEBUG
@@ -170208,7 +178502,6 @@ static void fts5yyStackOverflow(fts5yyParser *fts5yypParser, fts5YYMINORTYPE *ft
    ** stack every overflows */
 /******** Begin %stack_overflow code ******************************************/
 
-  UNUSED_PARAM(fts5yypMinor); /* Silence a compiler warning */
   sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
 /******** End %stack_overflow code ********************************************/
    sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
@@ -170241,7 +178534,7 @@ static void fts5yy_shift(
   fts5yyParser *fts5yypParser,          /* The parser to be shifted */
   int fts5yyNewState,               /* The new state to shift in */
   int fts5yyMajor,                  /* The major token to shift in */
-  fts5YYMINORTYPE *fts5yypMinor         /* Pointer to the minor token to shift in */
+  sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor        /* The minor token to shift in */
 ){
   fts5yyStackEntry *fts5yytos;
   fts5yypParser->fts5yyidx++;
@@ -170252,14 +178545,14 @@ static void fts5yy_shift(
 #endif
 #if fts5YYSTACKDEPTH>0 
   if( fts5yypParser->fts5yyidx>=fts5YYSTACKDEPTH ){
-    fts5yyStackOverflow(fts5yypParser, fts5yypMinor);
+    fts5yyStackOverflow(fts5yypParser);
     return;
   }
 #else
   if( fts5yypParser->fts5yyidx>=fts5yypParser->fts5yystksz ){
     fts5yyGrowStack(fts5yypParser);
     if( fts5yypParser->fts5yyidx>=fts5yypParser->fts5yystksz ){
-      fts5yyStackOverflow(fts5yypParser, fts5yypMinor);
+      fts5yyStackOverflow(fts5yypParser);
       return;
     }
   }
@@ -170267,7 +178560,7 @@ static void fts5yy_shift(
   fts5yytos = &fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx];
   fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
   fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
-  fts5yytos->minor = *fts5yypMinor;
+  fts5yytos->minor.fts5yy0 = fts5yyMinor;
   fts5yyTraceShift(fts5yypParser, fts5yyNewState);
 }
 
@@ -170312,24 +178605,46 @@ static void fts5yy_accept(fts5yyParser*);  /* Forward Declaration */
 */
 static void fts5yy_reduce(
   fts5yyParser *fts5yypParser,         /* The parser */
-  int fts5yyruleno                 /* Number of the rule by which to reduce */
+  unsigned int fts5yyruleno        /* Number of the rule by which to reduce */
 ){
   int fts5yygoto;                     /* The next state */
   int fts5yyact;                      /* The next action */
-  fts5YYMINORTYPE fts5yygotominor;        /* The LHS of the rule reduced */
   fts5yyStackEntry *fts5yymsp;            /* The top of the parser's stack */
   int fts5yysize;                     /* Amount to pop the stack */
   sqlite3Fts5ParserARG_FETCH;
   fts5yymsp = &fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx];
 #ifndef NDEBUG
-  if( fts5yyTraceFILE && fts5yyruleno>=0 
-        && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
+  if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
     fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
     fprintf(fts5yyTraceFILE, "%sReduce [%s], go to state %d.\n", fts5yyTracePrompt,
       fts5yyRuleName[fts5yyruleno], fts5yymsp[-fts5yysize].stateno);
   }
 #endif /* NDEBUG */
-  fts5yygotominor = fts5yyzerominor;
+
+  /* Check that the stack is large enough to grow by a single entry
+  ** if the RHS of the rule is empty.  This ensures that there is room
+  ** enough on the stack to push the LHS value */
+  if( fts5yyRuleInfo[fts5yyruleno].nrhs==0 ){
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+    if( fts5yypParser->fts5yyidx>fts5yypParser->fts5yyidxMax ){
+      fts5yypParser->fts5yyidxMax = fts5yypParser->fts5yyidx;
+    }
+#endif
+#if fts5YYSTACKDEPTH>0 
+    if( fts5yypParser->fts5yyidx>=fts5YYSTACKDEPTH-1 ){
+      fts5yyStackOverflow(fts5yypParser);
+      return;
+    }
+#else
+    if( fts5yypParser->fts5yyidx>=fts5yypParser->fts5yystksz-1 ){
+      fts5yyGrowStack(fts5yypParser);
+      if( fts5yypParser->fts5yyidx>=fts5yypParser->fts5yystksz-1 ){
+        fts5yyStackOverflow(fts5yypParser);
+        return;
+      }
+    }
+#endif
+  }
 
   switch( fts5yyruleno ){
   /* Beginning here are the reduction cases.  A typical example
@@ -170341,105 +178656,122 @@ static void fts5yy_reduce(
   **     break;
   */
 /********** Begin reduce actions **********************************************/
+        fts5YYMINORTYPE fts5yylhsminor;
       case 0: /* input ::= expr */
 { sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy18); }
         break;
       case 1: /* expr ::= expr AND expr */
 {
-  fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+  fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
 }
+  fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
         break;
       case 2: /* expr ::= expr OR expr */
 {
-  fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+  fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
 }
+  fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
         break;
       case 3: /* expr ::= expr NOT expr */
 {
-  fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+  fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
 }
+  fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
         break;
       case 4: /* expr ::= LP expr RP */
-{fts5yygotominor.fts5yy18 = fts5yymsp[-1].minor.fts5yy18;}
+{fts5yymsp[-2].minor.fts5yy18 = fts5yymsp[-1].minor.fts5yy18;}
         break;
       case 5: /* expr ::= exprlist */
       case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
-{fts5yygotominor.fts5yy18 = fts5yymsp[0].minor.fts5yy18;}
+{fts5yylhsminor.fts5yy18 = fts5yymsp[0].minor.fts5yy18;}
+  fts5yymsp[0].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
         break;
       case 7: /* exprlist ::= exprlist cnearset */
 {
-  fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-1].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+  fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18);
 }
+  fts5yymsp[-1].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
         break;
       case 8: /* cnearset ::= nearset */
 { 
-  fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26); 
+  fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26); 
 }
+  fts5yymsp[0].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
         break;
       case 9: /* cnearset ::= colset COLON nearset */
 { 
   sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy26, fts5yymsp[-2].minor.fts5yy3);
-  fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26); 
+  fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26); 
 }
+  fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
         break;
       case 10: /* colset ::= LCP colsetlist RCP */
-{ fts5yygotominor.fts5yy3 = fts5yymsp[-1].minor.fts5yy3; }
+{ fts5yymsp[-2].minor.fts5yy3 = fts5yymsp[-1].minor.fts5yy3; }
         break;
       case 11: /* colset ::= STRING */
 {
-  fts5yygotominor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+  fts5yylhsminor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
 }
+  fts5yymsp[0].minor.fts5yy3 = fts5yylhsminor.fts5yy3;
         break;
       case 12: /* colsetlist ::= colsetlist STRING */
 { 
-  fts5yygotominor.fts5yy3 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy3, &fts5yymsp[0].minor.fts5yy0); }
+  fts5yylhsminor.fts5yy3 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy3, &fts5yymsp[0].minor.fts5yy0); }
+  fts5yymsp[-1].minor.fts5yy3 = fts5yylhsminor.fts5yy3;
         break;
       case 13: /* colsetlist ::= STRING */
 { 
-  fts5yygotominor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); 
+  fts5yylhsminor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); 
 }
+  fts5yymsp[0].minor.fts5yy3 = fts5yylhsminor.fts5yy3;
         break;
       case 14: /* nearset ::= phrase */
-{ fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); }
+{ fts5yylhsminor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); }
+  fts5yymsp[0].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
         break;
       case 15: /* nearset ::= STRING LP nearphrases neardist_opt RP */
 {
   sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
   sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy26, &fts5yymsp[-1].minor.fts5yy0);
-  fts5yygotominor.fts5yy26 = fts5yymsp[-2].minor.fts5yy26;
+  fts5yylhsminor.fts5yy26 = fts5yymsp[-2].minor.fts5yy26;
 }
+  fts5yymsp[-4].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
         break;
       case 16: /* nearphrases ::= phrase */
 { 
-  fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); 
+  fts5yylhsminor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); 
 }
+  fts5yymsp[0].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
         break;
       case 17: /* nearphrases ::= nearphrases phrase */
 {
-  fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy26, fts5yymsp[0].minor.fts5yy11);
+  fts5yylhsminor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy26, fts5yymsp[0].minor.fts5yy11);
 }
+  fts5yymsp[-1].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
         break;
       case 18: /* neardist_opt ::= */
-{ fts5yygotominor.fts5yy0.p = 0; fts5yygotominor.fts5yy0.n = 0; }
+{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
         break;
       case 19: /* neardist_opt ::= COMMA STRING */
-{ fts5yygotominor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
+{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
         break;
       case 20: /* phrase ::= phrase PLUS STRING star_opt */
 { 
-  fts5yygotominor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy11, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
+  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy11, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
 }
+  fts5yymsp[-3].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
         break;
       case 21: /* phrase ::= STRING star_opt */
 { 
-  fts5yygotominor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
+  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
 }
+  fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
         break;
       case 22: /* star_opt ::= STAR */
-{ fts5yygotominor.fts5yy20 = 1; }
+{ fts5yymsp[0].minor.fts5yy20 = 1; }
         break;
       case 23: /* star_opt ::= */
-{ fts5yygotominor.fts5yy20 = 0; }
+{ fts5yymsp[1].minor.fts5yy20 = 0; }
         break;
       default:
         break;
@@ -170448,26 +178780,17 @@ static void fts5yy_reduce(
   assert( (size_t)fts5yyruleno<sizeof(fts5yyRuleInfo)/sizeof(fts5yyRuleInfo[0]) );
   fts5yygoto = fts5yyRuleInfo[fts5yyruleno].lhs;
   fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
-  fts5yypParser->fts5yyidx -= fts5yysize;
   fts5yyact = fts5yy_find_reduce_action(fts5yymsp[-fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
   if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
     if( fts5yyact>fts5YY_MAX_SHIFT ) fts5yyact += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
-    /* If the reduce action popped at least
-    ** one element off the stack, then we can push the new element back
-    ** onto the stack here, and skip the stack overflow test in fts5yy_shift().
-    ** That gives a significant speed improvement. */
-    if( fts5yysize ){
-      fts5yypParser->fts5yyidx++;
-      fts5yymsp -= fts5yysize-1;
-      fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
-      fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
-      fts5yymsp->minor = fts5yygotominor;
-      fts5yyTraceShift(fts5yypParser, fts5yyact);
-    }else{
-      fts5yy_shift(fts5yypParser,fts5yyact,fts5yygoto,&fts5yygotominor);
-    }
+    fts5yypParser->fts5yyidx -= fts5yysize - 1;
+    fts5yymsp -= fts5yysize-1;
+    fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
+    fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
+    fts5yyTraceShift(fts5yypParser, fts5yyact);
   }else{
     assert( fts5yyact == fts5YY_ACCEPT_ACTION );
+    fts5yypParser->fts5yyidx -= fts5yysize;
     fts5yy_accept(fts5yypParser);
   }
 }
@@ -170500,10 +178823,10 @@ static void fts5yy_parse_failed(
 static void fts5yy_syntax_error(
   fts5yyParser *fts5yypParser,           /* The parser */
   int fts5yymajor,                   /* The major type of the error token */
-  fts5YYMINORTYPE fts5yyminor            /* The minor type of the error token */
+  sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor         /* The minor type of the error token */
 ){
   sqlite3Fts5ParserARG_FETCH;
-#define FTS5TOKEN (fts5yyminor.fts5yy0)
+#define FTS5TOKEN fts5yyminor
 /************ Begin %syntax_error code ****************************************/
 
   UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */
@@ -170560,7 +178883,7 @@ static void sqlite3Fts5Parser(
   sqlite3Fts5ParserARG_PDECL               /* Optional %extra_argument parameter */
 ){
   fts5YYMINORTYPE fts5yyminorunion;
-  int fts5yyact;            /* The parser action. */
+  unsigned int fts5yyact;   /* The parser action. */
 #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
   int fts5yyendofinput;     /* True if we are at the end of input */
 #endif
@@ -170574,14 +178897,14 @@ static void sqlite3Fts5Parser(
   if( fts5yypParser->fts5yyidx<0 ){
 #if fts5YYSTACKDEPTH<=0
     if( fts5yypParser->fts5yystksz <=0 ){
-      /*memset(&fts5yyminorunion, 0, sizeof(fts5yyminorunion));*/
-      fts5yyminorunion = fts5yyzerominor;
-      fts5yyStackOverflow(fts5yypParser, &fts5yyminorunion);
+      fts5yyStackOverflow(fts5yypParser);
       return;
     }
 #endif
     fts5yypParser->fts5yyidx = 0;
+#ifndef fts5YYNOERRORRECOVERY
     fts5yypParser->fts5yyerrcnt = -1;
+#endif
     fts5yypParser->fts5yystack[0].stateno = 0;
     fts5yypParser->fts5yystack[0].major = 0;
 #ifndef NDEBUG
@@ -170591,7 +178914,6 @@ static void sqlite3Fts5Parser(
     }
 #endif
   }
-  fts5yyminorunion.fts5yy0 = fts5yyminor;
 #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
   fts5yyendofinput = (fts5yymajor==0);
 #endif
@@ -170607,13 +178929,16 @@ static void sqlite3Fts5Parser(
     fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
     if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
       if( fts5yyact > fts5YY_MAX_SHIFT ) fts5yyact += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
-      fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,&fts5yyminorunion);
+      fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor);
+#ifndef fts5YYNOERRORRECOVERY
       fts5yypParser->fts5yyerrcnt--;
+#endif
       fts5yymajor = fts5YYNOCODE;
     }else if( fts5yyact <= fts5YY_MAX_REDUCE ){
       fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE);
     }else{
       assert( fts5yyact == fts5YY_ERROR_ACTION );
+      fts5yyminorunion.fts5yy0 = fts5yyminor;
 #ifdef fts5YYERRORSYMBOL
       int fts5yymx;
 #endif
@@ -170643,7 +178968,7 @@ static void sqlite3Fts5Parser(
       **
       */
       if( fts5yypParser->fts5yyerrcnt<0 ){
-        fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminorunion);
+        fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminor);
       }
       fts5yymx = fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx].major;
       if( fts5yymx==fts5YYERRORSYMBOL || fts5yyerrorhit ){
@@ -170653,10 +178978,10 @@ static void sqlite3Fts5Parser(
              fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
         }
 #endif
-        fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+        fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
         fts5yymajor = fts5YYNOCODE;
       }else{
-         while(
+        while(
           fts5yypParser->fts5yyidx >= 0 &&
           fts5yymx != fts5YYERRORSYMBOL &&
           (fts5yyact = fts5yy_find_reduce_action(
@@ -170670,9 +178995,7 @@ static void sqlite3Fts5Parser(
           fts5yy_parse_failed(fts5yypParser);
           fts5yymajor = fts5YYNOCODE;
         }else if( fts5yymx!=fts5YYERRORSYMBOL ){
-          fts5YYMINORTYPE u2;
-          u2.fts5YYERRSYMDT = 0;
-          fts5yy_shift(fts5yypParser,fts5yyact,fts5YYERRORSYMBOL,&u2);
+          fts5yy_shift(fts5yypParser,fts5yyact,fts5YYERRORSYMBOL,fts5yyminor);
         }
       }
       fts5yypParser->fts5yyerrcnt = 3;
@@ -170685,7 +179008,7 @@ static void sqlite3Fts5Parser(
       ** Applications can set this macro (for example inside %include) if
       ** they intend to abandon the parse upon the first syntax error seen.
       */
-      fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminorunion);
+      fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
       fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
       fts5yymajor = fts5YYNOCODE;
       
@@ -170700,7 +179023,7 @@ static void sqlite3Fts5Parser(
       ** three input tokens have been successfully shifted.
       */
       if( fts5yypParser->fts5yyerrcnt<=0 ){
-        fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminorunion);
+        fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
       }
       fts5yypParser->fts5yyerrcnt = 3;
       fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
@@ -171387,7 +179710,7 @@ static void sqlite3Fts5BufferAppendString(
 static void sqlite3Fts5BufferAppendPrintf(
   int *pRc,
   Fts5Buffer *pBuf, 
-  char *zFmt, ...
+  const char *zFmt, ...
 ){
   if( *pRc==SQLITE_OK ){
     char *zTmp;
@@ -171700,6 +180023,7 @@ static void sqlite3Fts5TermsetFree(Fts5Termset *p){
 
 #define FTS5_DEFAULT_PAGE_SIZE   4050
 #define FTS5_DEFAULT_AUTOMERGE      4
+#define FTS5_DEFAULT_USERMERGE      4
 #define FTS5_DEFAULT_CRISISMERGE   16
 #define FTS5_DEFAULT_HASHSIZE    (1024*1024)
 
@@ -172123,7 +180447,9 @@ static const char *fts5ConfigGobbleWord(
       *pbQuoted = 1;
     }else{
       zRet = fts5ConfigSkipBareword(zIn);
-      zOut[zRet-zIn] = '\0';
+      if( zRet ){
+        zOut[zRet-zIn] = '\0';
+      }
     }
   }
 
@@ -172539,6 +180865,18 @@ static int sqlite3Fts5ConfigSetValue(
     }
   }
 
+  else if( 0==sqlite3_stricmp(zKey, "usermerge") ){
+    int nUsermerge = -1;
+    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+      nUsermerge = sqlite3_value_int(pVal);
+    }
+    if( nUsermerge<2 || nUsermerge>16 ){
+      *pbBadkey = 1;
+    }else{
+      pConfig->nUsermerge = nUsermerge;
+    }
+  }
+
   else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){
     int nCrisisMerge = -1;
     if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
@@ -172585,6 +180923,7 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
   /* Set default values */
   pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
   pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
+  pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
   pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
   pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
 
@@ -172886,6 +181225,8 @@ static int sqlite3Fts5ExprNew(
       pNew->nPhrase = sParse.nPhrase;
       sParse.apPhrase = 0;
     }
+  }else{
+    sqlite3Fts5ParseNodeFree(sParse.pExpr);
   }
 
   sqlite3_free(sParse.apPhrase);
@@ -173896,6 +182237,8 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
   if( Fts5NodeIsString(pNode) ){
     /* Initialize all term iterators in the NEAR object. */
     rc = fts5ExprNearInitAll(pExpr, pNode);
+  }else if( pNode->xNext==0 ){
+    pNode->bEof = 1;
   }else{
     int i;
     int nEof = 0;
@@ -173947,23 +182290,22 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
 */
 static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
   Fts5ExprNode *pRoot = p->pRoot;
-  int rc = SQLITE_OK;
-  if( pRoot->xNext ){
-    p->pIndex = pIdx;
-    p->bDesc = bDesc;
-    rc = fts5ExprNodeFirst(p, pRoot);
+  int rc;                         /* Return code */
 
-    /* If not at EOF but the current rowid occurs earlier than iFirst in
-    ** the iteration order, move to document iFirst or later. */
-    if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
-      rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
-    }
+  p->pIndex = pIdx;
+  p->bDesc = bDesc;
+  rc = fts5ExprNodeFirst(p, pRoot);
 
-    /* If the iterator is not at a real match, skip forward until it is. */
-    while( pRoot->bNomatch ){
-      assert( pRoot->bEof==0 && rc==SQLITE_OK );
-      rc = fts5ExprNodeNext(p, pRoot, 0, 0);
-    }
+  /* If not at EOF but the current rowid occurs earlier than iFirst in
+  ** the iteration order, move to document iFirst or later. */
+  if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
+    rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
+  }
+
+  /* If the iterator is not at a real match, skip forward until it is. */
+  while( pRoot->bNomatch ){
+    assert( pRoot->bEof==0 && rc==SQLITE_OK );
+    rc = fts5ExprNodeNext(p, pRoot, 0, 0);
   }
   return rc;
 }
@@ -174072,6 +182414,21 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset(
     sqlite3Fts5ParseNearsetFree(pNear);
     sqlite3Fts5ParsePhraseFree(pPhrase);
   }else{
+    if( pRet->nPhrase>0 ){
+      Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
+      assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
+      if( pPhrase->nTerm==0 ){
+        fts5ExprPhraseFree(pPhrase);
+        pRet->nPhrase--;
+        pParse->nPhrase--;
+        pPhrase = pLast;
+      }else if( pLast->nTerm==0 ){
+        fts5ExprPhraseFree(pLast);
+        pParse->apPhrase[pParse->nPhrase-2] = pPhrase;
+        pParse->nPhrase--;
+        pRet->nPhrase--;
+      }
+    }
     pRet->apPhrase[pRet->nPhrase++] = pPhrase;
   }
   return pRet;
@@ -174103,9 +182460,9 @@ static int fts5ParseTokenize(
 
   /* If an error has already occurred, this is a no-op */
   if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
+  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
 
-  assert( pPhrase==0 || pPhrase->nTerm>0 );
-  if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
+  if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
     Fts5ExprTerm *pSyn;
     size_t nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
     pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
@@ -174206,7 +182563,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
     pParse->rc = rc;
     fts5ExprPhraseFree(sCtx.pPhrase);
     sCtx.pPhrase = 0;
-  }else if( sCtx.pPhrase ){
+  }else{
 
     if( pAppend==0 ){
       if( (pParse->nPhrase % 8)==0 ){
@@ -174223,9 +182580,14 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
       pParse->nPhrase++;
     }
 
+    if( sCtx.pPhrase==0 ){
+      /* This happens when parsing a token or quoted phrase that contains
+      ** no token characters at all. (e.g ... MATCH '""'). */
+      sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
+    }else if( sCtx.pPhrase->nTerm ){
+      sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
+    }
     pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
-    assert( sCtx.pPhrase->nTerm>0 );
-    sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
   }
 
   return sCtx.pPhrase;
@@ -174260,6 +182622,17 @@ static int sqlite3Fts5ExprClonePhrase(
     pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, 
         sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
   }
+  if( rc==SQLITE_OK ){
+    Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
+    if( pColsetOrig ){
+      int nByte = sizeof(Fts5Colset) + pColsetOrig->nCol * sizeof(int);
+      Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
+      if( pColset ){ 
+        memcpy(pColset, pColsetOrig, nByte);
+      }
+      pNew->pRoot->pNear->pColset = pColset;
+    }
+  }
 
   for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
     int tflags = 0;
@@ -174321,23 +182694,25 @@ static void sqlite3Fts5ParseSetDistance(
   Fts5ExprNearset *pNear,
   Fts5Token *p
 ){
-  int nNear = 0;
-  int i;
-  if( p->n ){
-    for(i=0; i<p->n; i++){
-      char c = (char)p->p[i];
-      if( c<'0' || c>'9' ){
-        sqlite3Fts5ParseError(
-            pParse, "expected integer, got \"%.*s\"", p->n, p->p
-        );
-        return;
+  if( pNear ){
+    int nNear = 0;
+    int i;
+    if( p->n ){
+      for(i=0; i<p->n; i++){
+        char c = (char)p->p[i];
+        if( c<'0' || c>'9' ){
+          sqlite3Fts5ParseError(
+              pParse, "expected integer, got \"%.*s\"", p->n, p->p
+              );
+          return;
+        }
+        nNear = nNear * 10 + (p->p[i] - '0');
       }
-      nNear = nNear * 10 + (p->p[i] - '0');
+    }else{
+      nNear = FTS5_DEFAULT_NEARDIST;
     }
-  }else{
-    nNear = FTS5_DEFAULT_NEARDIST;
+    pNear->nNear = nNear;
   }
-  pNear->nNear = nNear;
 }
 
 /*
@@ -174524,10 +182899,14 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
         int iPhrase;
         for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
           pNear->apPhrase[iPhrase]->pNode = pRet;
+          if( pNear->apPhrase[iPhrase]->nTerm==0 ){
+            pRet->xNext = 0;
+            pRet->eType = FTS5_EOF;
+          }
         }
 
         if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL 
-         && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm!=1)
+         && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1)
         ){
           assert( pParse->rc==SQLITE_OK );
           pParse->rc = SQLITE_ERROR;
@@ -174556,6 +182935,70 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
   return pRet;
 }
 
+static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
+  Fts5Parse *pParse,              /* Parse context */
+  Fts5ExprNode *pLeft,            /* Left hand child expression */
+  Fts5ExprNode *pRight            /* Right hand child expression */
+){
+  Fts5ExprNode *pRet = 0;
+  Fts5ExprNode *pPrev;
+
+  if( pParse->rc ){
+    sqlite3Fts5ParseNodeFree(pLeft);
+    sqlite3Fts5ParseNodeFree(pRight);
+  }else{
+
+    assert( pLeft->eType==FTS5_STRING 
+        || pLeft->eType==FTS5_TERM
+        || pLeft->eType==FTS5_EOF
+        || pLeft->eType==FTS5_AND
+    );
+    assert( pRight->eType==FTS5_STRING 
+        || pRight->eType==FTS5_TERM 
+        || pRight->eType==FTS5_EOF 
+    );
+
+    if( pLeft->eType==FTS5_AND ){
+      pPrev = pLeft->apChild[pLeft->nChild-1];
+    }else{
+      pPrev = pLeft;
+    }
+    assert( pPrev->eType==FTS5_STRING 
+        || pPrev->eType==FTS5_TERM 
+        || pPrev->eType==FTS5_EOF 
+        );
+
+    if( pRight->eType==FTS5_EOF ){
+      assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] );
+      sqlite3Fts5ParseNodeFree(pRight);
+      pRet = pLeft;
+      pParse->nPhrase--;
+    }
+    else if( pPrev->eType==FTS5_EOF ){
+      Fts5ExprPhrase **ap;
+
+      if( pPrev==pLeft ){
+        pRet = pRight;
+      }else{
+        pLeft->apChild[pLeft->nChild-1] = pRight;
+        pRet = pLeft;
+      }
+
+      ap = &pParse->apPhrase[pParse->nPhrase-1-pRight->pNear->nPhrase];
+      assert( ap[0]==pPrev->pNear->apPhrase[0] );
+      memmove(ap, &ap[1], sizeof(Fts5ExprPhrase*)*pRight->pNear->nPhrase);
+      pParse->nPhrase--;
+
+      sqlite3Fts5ParseNodeFree(pPrev);
+    }
+    else{
+      pRet = sqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0);
+    }
+  }
+
+  return pRet;
+}
+
 static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
   size_t nByte = 0;
   Fts5ExprTerm *p;
@@ -174690,6 +183133,9 @@ static char *fts5ExprPrintTcl(
 
 static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
   char *zRet = 0;
+  if( pExpr->eType==0 ){
+    return sqlite3_mprintf("\"\"");
+  }else
   if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
     Fts5ExprNearset *pNear = pExpr->pNear;
     int i; 
@@ -174750,7 +183196,7 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
         zRet = 0;
       }else{
         int e = pExpr->apChild[i]->eType;
-        int b = (e!=FTS5_STRING && e!=FTS5_TERM);
+        int b = (e!=FTS5_STRING && e!=FTS5_TERM && e!=FTS5_EOF);
         zRet = fts5PrintfAppend(zRet, "%s%s%z%s", 
             (i==0 ? "" : zOp),
             (b?"(":""), z, (b?")":"")
@@ -175028,12 +183474,13 @@ static int fts5ExprPopulatePoslistsCb(
 
   UNUSED_PARAM2(iUnused1, iUnused2);
 
+  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
   if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
   for(i=0; i<pExpr->nPhrase; i++){
     Fts5ExprTerm *pTerm;
     if( p->aPopulator[i].bOk==0 ) continue;
     for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
-      int nTerm = strlen(pTerm->zTerm);
+      int nTerm = (int)strlen(pTerm->zTerm);
       if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix))
        && memcmp(pTerm->zTerm, pToken, nTerm)==0
       ){
@@ -175534,11 +183981,11 @@ static int sqlite3Fts5HashWrite(
         if( pHash->eDetail==FTS5_DETAIL_FULL ){
           pPtr[p->nData++] = 0x01;
           p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
-          p->iCol = iCol;
+          p->iCol = (i16)iCol;
           p->iPos = 0;
         }else{
           bNew = 1;
-          p->iCol = iPos = iCol;
+          p->iCol = (i16)(iPos = iCol);
         }
       }
 
@@ -176021,6 +184468,10 @@ struct Fts5Index {
   sqlite3_stmt *pIdxDeleter;      /* "DELETE FROM %_idx WHERE segid=? */
   sqlite3_stmt *pIdxSelect;
   int nRead;                      /* Total number of blocks read */
+
+  sqlite3_stmt *pDataVersion;
+  i64 iStructVersion;             /* data_version when pStruct read */
+  Fts5Structure *pStruct;         /* Current db structure (or NULL) */
 };
 
 struct Fts5DoclistIter {
@@ -176415,6 +184866,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
   return pRet;
 }
 
+
 /*
 ** Release a reference to data record returned by an earlier call to
 ** fts5DataRead().
@@ -176582,7 +185034,7 @@ static int fts5StructureDecode(
 
     for(iLvl=0; rc==SQLITE_OK && iLvl<nLevel; iLvl++){
       Fts5StructureLevel *pLvl = &pRet->aLevel[iLvl];
-      int nTotal;
+      int nTotal = 0;
       int iSeg;
 
       if( i>=nData ){
@@ -176675,6 +185127,50 @@ static void fts5StructureExtendLevel(
   }
 }
 
+static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
+  Fts5Structure *pRet = 0;
+  Fts5Config *pConfig = p->pConfig;
+  int iCookie;                    /* Configuration cookie */
+  Fts5Data *pData;
+
+  pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
+  if( p->rc==SQLITE_OK ){
+    /* TODO: Do we need this if the leaf-index is appended? Probably... */
+    memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
+    p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
+    if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
+      p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
+    }
+    fts5DataRelease(pData);
+    if( p->rc!=SQLITE_OK ){
+      fts5StructureRelease(pRet);
+      pRet = 0;
+    }
+  }
+
+  return pRet;
+}
+
+static i64 fts5IndexDataVersion(Fts5Index *p){
+  i64 iVersion = 0;
+
+  if( p->rc==SQLITE_OK ){
+    if( p->pDataVersion==0 ){
+      p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, 
+          sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb)
+          );
+      if( p->rc ) return 0;
+    }
+
+    if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){
+      iVersion = sqlite3_column_int64(p->pDataVersion, 0);
+    }
+    p->rc = sqlite3_reset(p->pDataVersion);
+  }
+
+  return iVersion;
+}
+
 /*
 ** Read, deserialize and return the structure record.
 **
@@ -176687,26 +185183,49 @@ static void fts5StructureExtendLevel(
 ** is called, it is a no-op.
 */
 static Fts5Structure *fts5StructureRead(Fts5Index *p){
-  Fts5Config *pConfig = p->pConfig;
-  Fts5Structure *pRet = 0;        /* Object to return */
-  int iCookie;                    /* Configuration cookie */
-  Fts5Data *pData;
 
-  pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
-  if( p->rc ) return 0;
-  /* TODO: Do we need this if the leaf-index is appended? Probably... */
-  memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
-  p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
-  if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
-    p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
+  if( p->pStruct==0 ){
+    p->iStructVersion = fts5IndexDataVersion(p);
+    if( p->rc==SQLITE_OK ){
+      p->pStruct = fts5StructureReadUncached(p);
+    }
   }
 
-  fts5DataRelease(pData);
-  if( p->rc!=SQLITE_OK ){
-    fts5StructureRelease(pRet);
-    pRet = 0;
+#if 0
+  else{
+    Fts5Structure *pTest = fts5StructureReadUncached(p);
+    if( pTest ){
+      int i, j;
+      assert_nc( p->pStruct->nSegment==pTest->nSegment );
+      assert_nc( p->pStruct->nLevel==pTest->nLevel );
+      for(i=0; i<pTest->nLevel; i++){
+        assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge );
+        assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg );
+        for(j=0; j<pTest->aLevel[i].nSeg; j++){
+          Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j];
+          Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j];
+          assert_nc( p1->iSegid==p2->iSegid );
+          assert_nc( p1->pgnoFirst==p2->pgnoFirst );
+          assert_nc( p1->pgnoLast==p2->pgnoLast );
+        }
+      }
+      fts5StructureRelease(pTest);
+    }
+  }
+#endif
+
+  if( p->rc!=SQLITE_OK ) return 0;
+  assert( p->iStructVersion!=0 );
+  assert( p->pStruct!=0 );
+  fts5StructureRef(p->pStruct);
+  return p->pStruct;
+}
+
+static void fts5StructureInvalidate(Fts5Index *p){
+  if( p->pStruct ){
+    fts5StructureRelease(p->pStruct);
+    p->pStruct = 0;
   }
-  return pRet;
 }
 
 /*
@@ -177871,6 +186390,10 @@ static void fts5LeafSeek(
   iPgidx = szLeaf;
   iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
   iOff = iTermOff;
+  if( iOff>n ){
+    p->rc = FTS5_CORRUPT;
+    return;
+  }
 
   while( 1 ){
 
@@ -177962,6 +186485,18 @@ static void fts5LeafSeek(
   fts5SegIterLoadNPos(p, pIter);
 }
 
+static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){
+  if( p->pIdxSelect==0 ){
+    Fts5Config *pConfig = p->pConfig;
+    fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
+          "SELECT pgno FROM '%q'.'%q_idx' WHERE "
+          "segid=? AND term<=? ORDER BY term DESC LIMIT 1",
+          pConfig->zDb, pConfig->zName
+    ));
+  }
+  return p->pIdxSelect;
+}
+
 /*
 ** Initialize the object pIter to point to term pTerm/nTerm within segment
 ** pSeg. If there is no such term in the index, the iterator is set to EOF.
@@ -177979,6 +186514,7 @@ static void fts5SegIterSeekInit(
   int iPg = 1;
   int bGe = (flags & FTS5INDEX_QUERY_SCAN);
   int bDlidx = 0;                 /* True if there is a doclist-index */
+  sqlite3_stmt *pIdxSelect = 0;
 
   assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 );
   assert( pTerm && nTerm );
@@ -177987,23 +186523,16 @@ static void fts5SegIterSeekInit(
 
   /* This block sets stack variable iPg to the leaf page number that may
   ** contain term (pTerm/nTerm), if it is present in the segment. */
-  if( p->pIdxSelect==0 ){
-    Fts5Config *pConfig = p->pConfig;
-    fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
-          "SELECT pgno FROM '%q'.'%q_idx' WHERE "
-          "segid=? AND term<=? ORDER BY term DESC LIMIT 1",
-          pConfig->zDb, pConfig->zName
-    ));
-  }
+  pIdxSelect = fts5IdxSelectStmt(p);
   if( p->rc ) return;
-  sqlite3_bind_int(p->pIdxSelect, 1, pSeg->iSegid);
-  sqlite3_bind_blob(p->pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
-  if( SQLITE_ROW==sqlite3_step(p->pIdxSelect) ){
-    i64 val = sqlite3_column_int(p->pIdxSelect, 0);
+  sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid);
+  sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
+  if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){
+    i64 val = sqlite3_column_int(pIdxSelect, 0);
     iPg = (int)(val>>1);
     bDlidx = (val & 0x0001);
   }
-  p->rc = sqlite3_reset(p->pIdxSelect);
+  p->rc = sqlite3_reset(pIdxSelect);
 
   if( iPg<pSeg->pgnoFirst ){
     iPg = pSeg->pgnoFirst;
@@ -178879,7 +187408,7 @@ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
         if( aiCol==aiColEnd ) goto setoutputs_col_out;
       }
       if( *aiCol==iPrev ){
-        *aOut++ = (iPrev - iPrevOut) + 2;
+        *aOut++ = (u8)((iPrev - iPrevOut) + 2);
         iPrevOut = iPrev;
       }
     }
@@ -179165,18 +187694,46 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
     if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){
       p->rc = SQLITE_FULL;
     }else{
-      while( iSegid==0 ){
-        int iLvl, iSeg;
-        sqlite3_randomness(sizeof(u32), (void*)&iSegid);
-        iSegid = iSegid & ((1 << FTS5_DATA_ID_B)-1);
-        for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
-          for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
-            if( iSegid==pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ){
-              iSegid = 0;
-            }
+      /* FTS5_MAX_SEGMENT is currently defined as 2000. So the following
+      ** array is 63 elements, or 252 bytes, in size.  */
+      u32 aUsed[(FTS5_MAX_SEGMENT+31) / 32];
+      int iLvl, iSeg;
+      int i;
+      u32 mask;
+      memset(aUsed, 0, sizeof(aUsed));
+      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+          int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
+          if( iId<=FTS5_MAX_SEGMENT ){
+            aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32);
           }
         }
       }
+
+      for(i=0; aUsed[i]==0xFFFFFFFF; i++);
+      mask = aUsed[i];
+      for(iSegid=0; mask & (1 << iSegid); iSegid++);
+      iSegid += 1 + i*32;
+
+#ifdef SQLITE_DEBUG
+      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+          assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
+        }
+      }
+      assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
+
+      {
+        sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
+        if( p->rc==SQLITE_OK ){
+          u8 aBlob[2] = {0xff, 0xff};
+          sqlite3_bind_int(pIdxSelect, 1, iSegid);
+          sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
+          assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
+          p->rc = sqlite3_reset(pIdxSelect);
+        }
+      }
+#endif
     }
   }
 
@@ -179621,7 +188178,9 @@ static void fts5WriteFinish(
       fts5WriteFlushLeaf(p, pWriter);
     }
     *pnLeaf = pLeaf->pgno-1;
-    fts5WriteFlushBtree(p, pWriter);
+    if( pLeaf->pgno>1 ){
+      fts5WriteFlushBtree(p, pWriter);
+    }
   }
   fts5BufferFree(&pLeaf->term);
   fts5BufferFree(&pLeaf->buf);
@@ -179891,13 +188450,17 @@ static void fts5IndexMergeLevel(
 
 /*
 ** Do up to nPg pages of automerge work on the index.
+**
+** Return true if any changes were actually made, or false otherwise.
 */
-static void fts5IndexMerge(
+static int fts5IndexMerge(
   Fts5Index *p,                   /* FTS5 backend object */
   Fts5Structure **ppStruct,       /* IN/OUT: Current structure of index */
-  int nPg                         /* Pages of work to do */
+  int nPg,                        /* Pages of work to do */
+  int nMin                        /* Minimum number of segments to merge */
 ){
   int nRem = nPg;
+  int bRet = 0;
   Fts5Structure *pStruct = *ppStruct;
   while( nRem>0 && p->rc==SQLITE_OK ){
     int iLvl;                   /* To iterate through levels */
@@ -179928,17 +188491,17 @@ static void fts5IndexMerge(
     }
 #endif
 
-    if( nBest<p->pConfig->nAutomerge 
-        && pStruct->aLevel[iBestLvl].nMerge==0 
-      ){
+    if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
       break;
     }
+    bRet = 1;
     fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
     if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
       fts5StructurePromote(p, iBestLvl+1, pStruct);
     }
   }
   *ppStruct = pStruct;
+  return bRet;
 }
 
 /*
@@ -179966,7 +188529,7 @@ static void fts5IndexAutomerge(
     pStruct->nWriteCounter += nLeaf;
     nRem = (int)(p->nWorkUnit * nWork * pStruct->nLevel);
 
-    fts5IndexMerge(p, ppStruct, nRem);
+    fts5IndexMerge(p, ppStruct, nRem, p->pConfig->nAutomerge);
   }
 }
 
@@ -180036,6 +188599,7 @@ static void fts5FlushOneHash(Fts5Index *p){
   ** for the new level-0 segment.  */
   pStruct = fts5StructureRead(p);
   iSegid = fts5AllocateSegid(p, pStruct);
+  fts5StructureInvalidate(p);
 
   if( iSegid ){
     const int pgsz = p->pConfig->pgsz;
@@ -180186,28 +188750,41 @@ static void fts5IndexFlush(Fts5Index *p){
   }
 }
 
-
-static int sqlite3Fts5IndexOptimize(Fts5Index *p){
-  Fts5Structure *pStruct;
+static Fts5Structure *fts5IndexOptimizeStruct(
+  Fts5Index *p, 
+  Fts5Structure *pStruct
+){
   Fts5Structure *pNew = 0;
-  int nSeg = 0;
-
-  assert( p->rc==SQLITE_OK );
-  fts5IndexFlush(p);
-  pStruct = fts5StructureRead(p);
+  size_t nByte = sizeof(Fts5Structure);
+  int nSeg = pStruct->nSegment;
+  int i;
 
-  if( pStruct ){
-    assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
-    nSeg = pStruct->nSegment;
-    if( nSeg>1 ){
-      size_t nByte = sizeof(Fts5Structure);
-      nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
-      pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
+  /* Figure out if this structure requires optimization. A structure does
+  ** not require optimization if either:
+  **
+  **  + it consists of fewer than two segments, or 
+  **  + all segments are on the same level, or
+  **  + all segments except one are currently inputs to a merge operation.
+  **
+  ** In the first case, return NULL. In the second, increment the ref-count
+  ** on *pStruct and return a copy of the pointer to it.
+  */
+  if( nSeg<2 ) return 0;
+  for(i=0; i<pStruct->nLevel; i++){
+    int nThis = pStruct->aLevel[i].nSeg;
+    if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
+      fts5StructureRef(pStruct);
+      return pStruct;
     }
+    assert( pStruct->aLevel[i].nMerge<=nThis );
   }
+
+  nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
+  pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
+
   if( pNew ){
     Fts5StructureLevel *pLvl;
-    size_t nByte = nSeg * sizeof(Fts5StructureSegment);
+    nByte = nSeg * sizeof(Fts5StructureSegment);
     pNew->nLevel = pStruct->nLevel+1;
     pNew->nRef = 1;
     pNew->nWriteCounter = pStruct->nWriteCounter;
@@ -180216,7 +188793,10 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){
     if( pLvl->aSeg ){
       int iLvl, iSeg;
       int iSegOut = 0;
-      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+      /* Iterate through all segments, from oldest to newest. Add them to
+      ** the new Fts5Level object so that pLvl->aSeg[0] is the oldest
+      ** segment in the data structure.  */
+      for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){
         for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
           pLvl->aSeg[iSegOut] = pStruct->aLevel[iLvl].aSeg[iSeg];
           iSegOut++;
@@ -180229,8 +188809,27 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){
     }
   }
 
+  return pNew;
+}
+
+static int sqlite3Fts5IndexOptimize(Fts5Index *p){
+  Fts5Structure *pStruct;
+  Fts5Structure *pNew = 0;
+
+  assert( p->rc==SQLITE_OK );
+  fts5IndexFlush(p);
+  pStruct = fts5StructureRead(p);
+  fts5StructureInvalidate(p);
+
+  if( pStruct ){
+    pNew = fts5IndexOptimizeStruct(p, pStruct);
+  }
+  fts5StructureRelease(pStruct);
+
+  assert( pNew==0 || pNew->nSegment>0 );
   if( pNew ){
-    int iLvl = pNew->nLevel-1;
+    int iLvl;
+    for(iLvl=0; pNew->aLevel[iLvl].nSeg==0; iLvl++){}
     while( p->rc==SQLITE_OK && pNew->aLevel[iLvl].nSeg>0 ){
       int nRem = FTS5_OPT_WORK_UNIT;
       fts5IndexMergeLevel(p, &pNew, iLvl, &nRem);
@@ -180240,20 +188839,32 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){
     fts5StructureRelease(pNew);
   }
 
-  fts5StructureRelease(pStruct);
   return fts5IndexReturn(p); 
 }
 
+/*
+** This is called to implement the special "VALUES('merge', $nMerge)"
+** INSERT command.
+*/
 static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
-  Fts5Structure *pStruct;
-
-  pStruct = fts5StructureRead(p);
-  if( pStruct && pStruct->nLevel ){
-    fts5IndexMerge(p, &pStruct, nMerge);
-    fts5StructureWrite(p, pStruct);
+  Fts5Structure *pStruct = fts5StructureRead(p);
+  if( pStruct ){
+    int nMin = p->pConfig->nUsermerge;
+    fts5StructureInvalidate(p);
+    if( nMerge<0 ){
+      Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
+      fts5StructureRelease(pStruct);
+      pStruct = pNew;
+      nMin = 2;
+      nMerge = nMerge*-1;
+    }
+    if( pStruct && pStruct->nLevel ){
+      if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
+        fts5StructureWrite(p, pStruct);
+      }
+    }
+    fts5StructureRelease(pStruct);
   }
-  fts5StructureRelease(pStruct);
-
   return fts5IndexReturn(p);
 }
 
@@ -180667,6 +189278,7 @@ static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
 static int sqlite3Fts5IndexRollback(Fts5Index *p){
   fts5CloseReader(p);
   fts5IndexDiscardData(p);
+  fts5StructureInvalidate(p);
   /* assert( p->rc==SQLITE_OK ); */
   return SQLITE_OK;
 }
@@ -180678,6 +189290,7 @@ static int sqlite3Fts5IndexRollback(Fts5Index *p){
 */
 static int sqlite3Fts5IndexReinit(Fts5Index *p){
   Fts5Structure s;
+  fts5StructureInvalidate(p);
   memset(&s, 0, sizeof(Fts5Structure));
   fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
   fts5StructureWrite(p, &s);
@@ -180736,11 +189349,13 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){
   int rc = SQLITE_OK;
   if( p ){
     assert( p->pReader==0 );
+    fts5StructureInvalidate(p);
     sqlite3_finalize(p->pWriter);
     sqlite3_finalize(p->pDeleter);
     sqlite3_finalize(p->pIdxWriter);
     sqlite3_finalize(p->pIdxDeleter);
     sqlite3_finalize(p->pIdxSelect);
+    sqlite3_finalize(p->pDataVersion);
     sqlite3Fts5HashFree(p->pHash);
     sqlite3_free(p->zDataTbl);
     sqlite3_free(p);
@@ -181997,6 +190612,15 @@ static int sqlite3Fts5IndexInit(sqlite3 *db){
   return rc;
 }
 
+
+static int sqlite3Fts5IndexReset(Fts5Index *p){
+  assert( p->pStruct==0 || p->iStructVersion!=0 );
+  if( fts5IndexDataVersion(p)!=p->iStructVersion ){
+    fts5StructureInvalidate(p);
+  }
+  return fts5IndexReturn(p);
+}
+
 /*
 ** 2014 Jun 09
 **
@@ -182598,27 +191222,38 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
   return SQLITE_OK;
 }
 
+static int fts5NewTransaction(Fts5Table *pTab){
+  Fts5Cursor *pCsr;
+  for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
+    if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
+  }
+  return sqlite3Fts5StorageReset(pTab->pStorage);
+}
+
 /*
 ** Implementation of xOpen method.
 */
 static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
   Fts5Table *pTab = (Fts5Table*)pVTab;
   Fts5Config *pConfig = pTab->pConfig;
-  Fts5Cursor *pCsr;               /* New cursor object */
+  Fts5Cursor *pCsr = 0;           /* New cursor object */
   size_t nByte;                   /* Bytes of space to allocate */
-  int rc = SQLITE_OK;             /* Return code */
+  int rc;                         /* Return code */
 
-  nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
-  pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
-  if( pCsr ){
-    Fts5Global *pGlobal = pTab->pGlobal;
-    memset(pCsr, 0, nByte);
-    pCsr->aColumnSize = (int*)&pCsr[1];
-    pCsr->pNext = pGlobal->pCsr;
-    pGlobal->pCsr = pCsr;
-    pCsr->iCsrId = ++pGlobal->iNextId;
-  }else{
-    rc = SQLITE_NOMEM;
+  rc = fts5NewTransaction(pTab);
+  if( rc==SQLITE_OK ){
+    nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
+    pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
+    if( pCsr ){
+      Fts5Global *pGlobal = pTab->pGlobal;
+      memset(pCsr, 0, nByte);
+      pCsr->aColumnSize = (int*)&pCsr[1];
+      pCsr->pNext = pGlobal->pCsr;
+      pGlobal->pCsr = pCsr;
+      pCsr->iCsrId = ++pGlobal->iNextId;
+    }else{
+      rc = SQLITE_NOMEM;
+    }
   }
   *ppCsr = (sqlite3_vtab_cursor*)pCsr;
   return rc;
@@ -183512,13 +192147,13 @@ static int fts5UpdateMethod(
       rc = SQLITE_ERROR;
     }
 
-    /* Case 1: DELETE */
+    /* DELETE */
     else if( nArg==1 ){
       i64 iDel = sqlite3_value_int64(apVal[0]);  /* Rowid to delete */
       rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
     }
 
-    /* Case 2: INSERT */
+    /* INSERT */
     else if( eType0!=SQLITE_INTEGER ){     
       /* If this is a REPLACE, first remove the current entry (if any) */
       if( eConflict==SQLITE_REPLACE 
@@ -183530,7 +192165,7 @@ static int fts5UpdateMethod(
       fts5StorageInsert(&rc, pTab, apVal, pRowid);
     }
 
-    /* Case 2: UPDATE */
+    /* UPDATE */
     else{
       i64 iOld = sqlite3_value_int64(apVal[0]);  /* Old rowid */
       i64 iNew = sqlite3_value_int64(apVal[1]);  /* New rowid */
@@ -183579,8 +192214,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
 ** Implementation of xBegin() method. 
 */
 static int fts5BeginMethod(sqlite3_vtab *pVtab){
-  UNUSED_PARAM(pVtab);  /* Call below is a no-op for NDEBUG builds */
   fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
+  fts5NewTransaction((Fts5Table*)pVtab);
   return SQLITE_OK;
 }
 
@@ -184605,7 +193240,7 @@ static void fts5SourceIdFunc(
 ){
   assert( nArg==0 );
   UNUSED_PARAM2(nArg, apUnused);
-  sqlite3_result_text(pCtx, "fts5: 2016-02-15 17:29:24 3d862f207e3adc00f78066799ac5a8c282430a5f", -1, SQLITE_TRANSIENT);
+  sqlite3_result_text(pCtx, "fts5: 2016-05-18 10:57:30 fc49f556e48970561d7ab6a2f24fdd7d9eb81ff2", -1, SQLITE_TRANSIENT);
 }
 
 static int fts5Init(sqlite3 *db){
@@ -184666,6 +193301,17 @@ static int fts5Init(sqlite3 *db){
       );
     }
   }
+
+  /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
+  ** fts5_test_mi.c is compiled and linked into the executable. And call
+  ** its entry point to enable the matchinfo() demo.  */
+#ifdef SQLITE_FTS5_ENABLE_TEST_MI
+  if( rc==SQLITE_OK ){
+    extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
+    rc = sqlite3Fts5TestRegisterMatchinfo(db);
+  }
+#endif
+
   return rc;
 }
 
@@ -184857,6 +193503,7 @@ static int fts5StorageGetStmt(
   }
 
   *ppStmt = p->aStmt[eStmt];
+  sqlite3_reset(*ppStmt);
   return rc;
 }
 
@@ -185080,6 +193727,7 @@ static int fts5StorageInsertCallback(
   Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
   Fts5Index *pIdx = pCtx->pStorage->pIndex;
   UNUSED_PARAM2(iUnused1, iUnused2);
+  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
   if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
     pCtx->szCol++;
   }
@@ -185351,6 +193999,10 @@ static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
   return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
 }
 
+static int sqlite3Fts5StorageReset(Fts5Storage *p){
+  return sqlite3Fts5IndexReset(p->pIndex);
+}
+
 /*
 ** Allocate a new rowid. This is used for "external content" tables when
 ** a NULL value is inserted into the rowid column. The new rowid is allocated
@@ -185522,6 +194174,7 @@ static int fts5StorageIntegrityCallback(
   int iCol;
 
   UNUSED_PARAM2(iUnused1, iUnused2);
+  if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
 
   if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
     pCtx->szCol++;
@@ -185834,8 +194487,6 @@ static int sqlite3Fts5StorageConfigValue(
   return rc;
 }
 
-
-
 /*
 ** 2014 May 31
 **
similarity index 85%
rename from pkgs/sqlite3.11.0/compat/sqlite3/sqlite3.h
rename to pkgs/sqlite3.13.0/compat/sqlite3/sqlite3.h
index cc63be1..bb3762d 100644 (file)
@@ -111,9 +111,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.11.0"
-#define SQLITE_VERSION_NUMBER 3011000
-#define SQLITE_SOURCE_ID      "2016-02-15 17:29:24 3d862f207e3adc00f78066799ac5a8c282430a5f"
+#define SQLITE_VERSION        "3.13.0"
+#define SQLITE_VERSION_NUMBER 3013000
+#define SQLITE_SOURCE_ID      "2016-05-18 10:57:30 fc49f556e48970561d7ab6a2f24fdd7d9eb81ff2"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -1228,7 +1228,7 @@ struct sqlite3_vfs {
   const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
   /*
   ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
-  ** New fields may be appended in figure versions.  The iVersion
+  ** New fields may be appended in future versions.  The iVersion
   ** value will increment whenever this happens. 
   */
 };
@@ -1727,6 +1727,20 @@ SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
 ** is enabled (using the [PRAGMA threads] command) and the amount of content
 ** to be sorted exceeds the page size times the minimum of the
 ** [PRAGMA cache_size] setting and this value.
+**
+** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
+** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
+** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
+** becomes the [statement journal] spill-to-disk threshold.  
+** [Statement journals] are held in memory until their size (in bytes)
+** exceeds this threshold, at which point they are written to disk.
+** Or if the threshold is -1, statement journals are always held
+** exclusively in memory.
+** Since many statement journals never become large, setting the spill
+** threshold to a value such as 64KiB can greatly reduce the amount of
+** I/O required to support statement rollback.
+** The default value for this setting is controlled by the
+** [SQLITE_STMTJRNL_SPILL] compile-time option.
 ** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
@@ -1752,6 +1766,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
 #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
 #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
 #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
+#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
@@ -1809,11 +1824,43 @@ SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
 ** following this call.  The second parameter may be a NULL pointer, in
 ** which case the trigger setting is not reported back. </dd>
 **
+** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+** <dd> ^This option is used to enable or disable the two-argument
+** version of the [fts3_tokenizer()] function which is part of the
+** [FTS3] full-text search engine extension.
+** There should be two additional arguments.
+** The first argument is an integer which is 0 to disable fts3_tokenizer() or
+** positive to enable fts3_tokenizer() or negative to leave the setting
+** unchanged.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
+** following this call.  The second parameter may be a NULL pointer, in
+** which case the new setting is not reported back. </dd>
+**
+** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+** interface independently of the [load_extension()] SQL function.
+** The [sqlite3_enable_load_extension()] API enables or disables both the
+** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
+** There should be two additional arguments.
+** When the first argument to this interface is 1, then only the C-API is
+** enabled and the SQL function remains disabled.  If the first argment to
+** this interface is 0, then both the C-API and the SQL function are disabled.
+** If the first argument is -1, then no changes are made to state of either the
+** C-API or the SQL function.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
+** is disabled or enabled following this call.  The second parameter may
+** be a NULL pointer, in which case the new setting is not reported back.
+** </dd>
+**
 ** </dl>
 */
-#define SQLITE_DBCONFIG_LOOKASIDE       1001  /* void* int int */
-#define SQLITE_DBCONFIG_ENABLE_FKEY     1002  /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_TRIGGER  1003  /* int int* */
+#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
+#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
 
 
 /*
@@ -5078,7 +5125,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
 ** ^The sqlite3_update_hook() interface registers a callback function
 ** with the [database connection] identified by the first argument
 ** to be invoked whenever a row is updated, inserted or deleted in
-** a rowid table.
+** a [rowid table].
 ** ^Any callback set by a previous call to this function
 ** for the same database connection is overridden.
 **
@@ -5117,8 +5164,8 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
 ** on the same [database connection] D, or NULL for
 ** the first call on D.
 **
-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
-** interfaces.
+** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
+** and [sqlite3_preupdate_hook()] interfaces.
 */
 SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
   sqlite3*, 
@@ -5366,9 +5413,18 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
 ** should free this memory by calling [sqlite3_free()].
 **
 ** ^Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] prior to calling this API,
+** [sqlite3_enable_load_extension()] or
+** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
+** prior to calling this API,
 ** otherwise an error will be returned.
 **
+** <b>Security warning:</b> It is recommended that the 
+** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
+** interface.  The use of the [sqlite3_enable_load_extension()] interface
+** should be avoided.  This will keep the SQL function [load_extension()]
+** disabled and prevent SQL injections from giving attackers
+** access to extension loading capabilities.
+**
 ** See also the [load_extension() SQL function].
 */
 SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
@@ -5391,6 +5447,17 @@ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
 ** ^Call the sqlite3_enable_load_extension() routine with onoff==1
 ** to turn extension loading on and call it with onoff==0 to turn
 ** it back off again.
+**
+** ^This interface enables or disables both the C-API
+** [sqlite3_load_extension()] and the SQL function [load_extension()].
+** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
+** to enable or disable only the C-API.
+**
+** <b>Security warning:</b> It is recommended that extension loading
+** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
+** rather than this interface, so the [load_extension()] SQL function
+** remains disabled. This will prevent SQL injections from giving attackers
+** access to extension loading capabilities.
 */
 SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
@@ -7031,7 +7098,7 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
 ** an error.
 **
-** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
+** ^A call to sqlite3_backup_init() will fail, returning NULL, if 
 ** there is already a read or read-write transaction open on the 
 ** destination database.
 **
@@ -7412,7 +7479,7 @@ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...)
 ** previously registered write-ahead log callback. ^Note that the
 ** [sqlite3_wal_autocheckpoint()] interface and the
 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** those overwrite any prior [sqlite3_wal_hook()] settings.
+** overwrite any prior [sqlite3_wal_hook()] settings.
 */
 SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
   sqlite3*, 
@@ -7812,6 +7879,114 @@ SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
 SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
 
 /*
+** CAPI3REF: The pre-update hook.
+**
+** ^These interfaces are only available if SQLite is compiled using the
+** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
+**
+** ^The [sqlite3_preupdate_hook()] interface registers a callback function
+** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
+** on a [rowid table].
+** ^At most one preupdate hook may be registered at a time on a single
+** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
+** the previous setting.
+** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
+** with a NULL pointer as the second parameter.
+** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
+** the first parameter to callbacks.
+**
+** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate
+** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID]
+** tables.
+**
+** ^The second parameter to the preupdate callback is a pointer to
+** the [database connection] that registered the preupdate hook.
+** ^The third parameter to the preupdate callback is one of the constants
+** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to indentify the
+** kind of update operation that is about to occur.
+** ^(The fourth parameter to the preupdate callback is the name of the
+** database within the database connection that is being modified.  This
+** will be "main" for the main database or "temp" for TEMP tables or 
+** the name given after the AS keyword in the [ATTACH] statement for attached
+** databases.)^
+** ^The fifth parameter to the preupdate callback is the name of the
+** table that is being modified.
+** ^The sixth parameter to the preupdate callback is the initial [rowid] of the
+** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is
+** undefined for SQLITE_INSERT changes.
+** ^The seventh parameter to the preupdate callback is the final [rowid] of
+** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is
+** undefined for SQLITE_DELETE changes.
+**
+** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
+** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
+** provide additional information about a preupdate event. These routines
+** may only be called from within a preupdate callback.  Invoking any of
+** these routines from outside of a preupdate callback or with a
+** [database connection] pointer that is different from the one supplied
+** to the preupdate callback results in undefined and probably undesirable
+** behavior.
+**
+** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
+** in the row that is being inserted, updated, or deleted.
+**
+** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row before it is updated.  The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
+** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
+** behavior is undefined.  The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row after it is updated.  The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
+** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
+** behavior is undefined.  The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
+** callback was invoked as a result of a direct insert, update, or delete
+** operation; or 1 for inserts, updates, or deletes invoked by top-level 
+** triggers; or 2 for changes resulting from triggers called by top-level
+** triggers; and so forth.
+**
+** See also:  [sqlite3_update_hook()]
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_preupdate_hook(
+  sqlite3 *db,
+  void(*xPreUpdate)(
+    void *pCtx,                   /* Copy of third arg to preupdate_hook() */
+    sqlite3 *db,                  /* Database handle */
+    int op,                       /* SQLITE_UPDATE, DELETE or INSERT */
+    char const *zDb,              /* Database name */
+    char const *zName,            /* Table name */
+    sqlite3_int64 iKey1,          /* Rowid of row about to be deleted/updated */
+    sqlite3_int64 iKey2           /* New rowid value (for a rowid UPDATE) */
+  ),
+  void*
+);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_count(sqlite3 *);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_depth(sqlite3 *);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+
+/*
+** CAPI3REF: Low-level system error code
+**
+** ^Attempt to return the underlying operating system error code or error
+** number that caused the most recent I/O error or failure to open a file.
+** The return value is OS-dependent.  For example, on unix systems, after
+** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
+** called to get back the underlying "errno" that caused the problem, such
+** as ENOSPC, EAUTH, EISDIR, and so forth.  
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*);
+
+/*
 ** CAPI3REF: Database Snapshot
 ** KEYWORDS: {snapshot}
 ** EXPERIMENTAL
@@ -7869,17 +8044,30 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
 ** CAPI3REF: Start a read transaction on an historical snapshot
 ** EXPERIMENTAL
 **
-** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
-** read transaction that is currently open on schema S of
-** [database connection] D so that it refers to historical [snapshot] P.
+** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
+** read transaction for schema S of
+** [database connection] D such that the read transaction
+** refers to historical [snapshot] P, rather than the most
+** recent change to the database.
 ** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
 ** or an appropriate [error code] if it fails.
 **
 ** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
-** the first operation, apart from other sqlite3_snapshot_open() calls,
-** following the [BEGIN] that starts a new read transaction.
-** ^A [snapshot] will fail to open if it has been overwritten by a 
-** [checkpoint].  
+** the first operation following the [BEGIN] that takes the schema S
+** out of [autocommit mode].
+** ^In other words, schema S must not currently be in
+** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
+** database connection D must be out of [autocommit mode].
+** ^A [snapshot] will fail to open if it has been overwritten by a
+** [checkpoint].
+** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+** database connection D does not know that the database file for
+** schema S is in [WAL mode].  A database connection might not know
+** that the database file is in [WAL mode] if there has been no prior
+** I/O on that database connection, or if the database entered [WAL mode] 
+** after the most recent I/O on the database connection.)^
+** (Hint: Run "[PRAGMA application_id]" against a newly opened
+** database connection in order to make it ready to use snapshots.)
 **
 ** The [sqlite3_snapshot_open()] interface is only available when the
 ** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
@@ -7904,6 +8092,33 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
 SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot*);
 
 /*
+** CAPI3REF: Compare the ages of two snapshot handles.
+** EXPERIMENTAL
+**
+** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+** of two valid snapshot handles. 
+**
+** If the two snapshot handles are not associated with the same database 
+** file, the result of the comparison is undefined. 
+**
+** Additionally, the result of the comparison is only valid if both of the
+** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
+** last time the wal file was deleted. The wal file is deleted when the
+** database is changed back to rollback mode or when the number of database
+** clients drops to zero. If either snapshot handle was obtained before the 
+** wal file was last deleted, the value returned by this function 
+** is undefined.
+**
+** Otherwise, this API returns a negative value if P1 refers to an older
+** snapshot than P2, zero if the two handles refer to the same database
+** snapshot, and a positive value if P1 is a newer snapshot than P2.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_cmp(
+  sqlite3_snapshot *p1,
+  sqlite3_snapshot *p2
+);
+
+/*
 ** Undo the hack that converts floating point types to integer for
 ** builds on processors without floating point support.
 */
@@ -7916,6 +8131,7 @@ SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3
 #endif
 #endif /* _SQLITE3_H_ */
 
+/******** Begin file sqlite3rtree.h *********/
 /*
 ** 2010 August 30
 **
@@ -8033,6 +8249,1287 @@ struct sqlite3_rtree_query_info {
 
 #endif  /* ifndef _SQLITE3RTREE_H_ */
 
+/******** End of sqlite3rtree.h *********/
+/******** Begin file sqlite3session.h *********/
+
+#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
+#define __SQLITESESSION_H_ 1
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+** CAPI3REF: Session Object Handle
+*/
+typedef struct sqlite3_session sqlite3_session;
+
+/*
+** CAPI3REF: Changeset Iterator Handle
+*/
+typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
+
+/*
+** CAPI3REF: Create A New Session Object
+**
+** Create a new session object attached to database handle db. If successful,
+** a pointer to the new object is written to *ppSession and SQLITE_OK is
+** returned. If an error occurs, *ppSession is set to NULL and an SQLite
+** error code (e.g. SQLITE_NOMEM) is returned.
+**
+** It is possible to create multiple session objects attached to a single
+** database handle.
+**
+** Session objects created using this function should be deleted using the
+** [sqlite3session_delete()] function before the database handle that they
+** are attached to is itself closed. If the database handle is closed before
+** the session object is deleted, then the results of calling any session
+** module function, including [sqlite3session_delete()] on the session object
+** are undefined.
+**
+** Because the session module uses the [sqlite3_preupdate_hook()] API, it
+** is not possible for an application to register a pre-update hook on a
+** database handle that has one or more session objects attached. Nor is
+** it possible to create a session object attached to a database handle for
+** which a pre-update hook is already defined. The results of attempting 
+** either of these things are undefined.
+**
+** The session object will be used to create changesets for tables in
+** database zDb, where zDb is either "main", or "temp", or the name of an
+** attached database. It is not an error if database zDb is not attached
+** to the database when the session object is created.
+*/
+int sqlite3session_create(
+  sqlite3 *db,                    /* Database handle */
+  const char *zDb,                /* Name of db (e.g. "main") */
+  sqlite3_session **ppSession     /* OUT: New session object */
+);
+
+/*
+** CAPI3REF: Delete A Session Object
+**
+** Delete a session object previously allocated using 
+** [sqlite3session_create()]. Once a session object has been deleted, the
+** results of attempting to use pSession with any other session module
+** function are undefined.
+**
+** Session objects must be deleted before the database handle to which they
+** are attached is closed. Refer to the documentation for 
+** [sqlite3session_create()] for details.
+*/
+void sqlite3session_delete(sqlite3_session *pSession);
+
+
+/*
+** CAPI3REF: Enable Or Disable A Session Object
+**
+** Enable or disable the recording of changes by a session object. When
+** enabled, a session object records changes made to the database. When
+** disabled - it does not. A newly created session object is enabled.
+** Refer to the documentation for [sqlite3session_changeset()] for further
+** details regarding how enabling and disabling a session object affects
+** the eventual changesets.
+**
+** Passing zero to this function disables the session. Passing a value
+** greater than zero enables it. Passing a value less than zero is a 
+** no-op, and may be used to query the current state of the session.
+**
+** The return value indicates the final state of the session object: 0 if 
+** the session is disabled, or 1 if it is enabled.
+*/
+int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
+
+/*
+** CAPI3REF: Set Or Clear the Indirect Change Flag
+**
+** Each change recorded by a session object is marked as either direct or
+** indirect. A change is marked as indirect if either:
+**
+** <ul>
+**   <li> The session object "indirect" flag is set when the change is
+**        made, or
+**   <li> The change is made by an SQL trigger or foreign key action 
+**        instead of directly as a result of a users SQL statement.
+** </ul>
+**
+** If a single row is affected by more than one operation within a session,
+** then the change is considered indirect if all operations meet the criteria
+** for an indirect change above, or direct otherwise.
+**
+** This function is used to set, clear or query the session object indirect
+** flag.  If the second argument passed to this function is zero, then the
+** indirect flag is cleared. If it is greater than zero, the indirect flag
+** is set. Passing a value less than zero does not modify the current value
+** of the indirect flag, and may be used to query the current state of the 
+** indirect flag for the specified session object.
+**
+** The return value indicates the final state of the indirect flag: 0 if 
+** it is clear, or 1 if it is set.
+*/
+int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
+
+/*
+** CAPI3REF: Attach A Table To A Session Object
+**
+** If argument zTab is not NULL, then it is the name of a table to attach
+** to the session object passed as the first argument. All subsequent changes 
+** made to the table while the session object is enabled will be recorded. See 
+** documentation for [sqlite3session_changeset()] for further details.
+**
+** Or, if argument zTab is NULL, then changes are recorded for all tables
+** in the database. If additional tables are added to the database (by 
+** executing "CREATE TABLE" statements) after this call is made, changes for 
+** the new tables are also recorded.
+**
+** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
+** defined as part of their CREATE TABLE statement. It does not matter if the 
+** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
+** KEY may consist of a single column, or may be a composite key.
+** 
+** It is not an error if the named table does not exist in the database. Nor
+** is it an error if the named table does not have a PRIMARY KEY. However,
+** no changes will be recorded in either of these scenarios.
+**
+** Changes are not recorded for individual rows that have NULL values stored
+** in one or more of their PRIMARY KEY columns.
+**
+** SQLITE_OK is returned if the call completes without error. Or, if an error 
+** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
+*/
+int sqlite3session_attach(
+  sqlite3_session *pSession,      /* Session object */
+  const char *zTab                /* Table name */
+);
+
+/*
+** CAPI3REF: Set a table filter on a Session Object.
+**
+** The second argument (xFilter) is the "filter callback". For changes to rows 
+** in tables that are not attached to the Session oject, the filter is called
+** to determine whether changes to the table's rows should be tracked or not. 
+** If xFilter returns 0, changes is not tracked. Note that once a table is 
+** attached, xFilter will not be called again.
+*/
+void sqlite3session_table_filter(
+  sqlite3_session *pSession,      /* Session object */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of third arg to _filter_table() */
+    const char *zTab              /* Table name */
+  ),
+  void *pCtx                      /* First argument passed to xFilter */
+);
+
+/*
+** CAPI3REF: Generate A Changeset From A Session Object
+**
+** Obtain a changeset containing changes to the tables attached to the 
+** session object passed as the first argument. If successful, 
+** set *ppChangeset to point to a buffer containing the changeset 
+** and *pnChangeset to the size of the changeset in bytes before returning
+** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
+** zero and return an SQLite error code.
+**
+** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
+** each representing a change to a single row of an attached table. An INSERT
+** change contains the values of each field of a new database row. A DELETE
+** contains the original values of each field of a deleted database row. An
+** UPDATE change contains the original values of each field of an updated
+** database row along with the updated values for each updated non-primary-key
+** column. It is not possible for an UPDATE change to represent a change that
+** modifies the values of primary key columns. If such a change is made, it
+** is represented in a changeset as a DELETE followed by an INSERT.
+**
+** Changes are not recorded for rows that have NULL values stored in one or 
+** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
+** no corresponding change is present in the changesets returned by this
+** function. If an existing row with one or more NULL values stored in
+** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
+** only an INSERT is appears in the changeset. Similarly, if an existing row
+** with non-NULL PRIMARY KEY values is updated so that one or more of its
+** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
+** DELETE change only.
+**
+** The contents of a changeset may be traversed using an iterator created
+** using the [sqlite3changeset_start()] API. A changeset may be applied to
+** a database with a compatible schema using the [sqlite3changeset_apply()]
+** API.
+**
+** Within a changeset generated by this function, all changes related to a
+** single table are grouped together. In other words, when iterating through
+** a changeset or when applying a changeset to a database, all changes related
+** to a single table are processed before moving on to the next table. Tables
+** are sorted in the same order in which they were attached (or auto-attached)
+** to the sqlite3_session object. The order in which the changes related to
+** a single table are stored is undefined.
+**
+** Following a successful call to this function, it is the responsibility of
+** the caller to eventually free the buffer that *ppChangeset points to using
+** [sqlite3_free()].
+**
+** <h3>Changeset Generation</h3>
+**
+** Once a table has been attached to a session object, the session object
+** records the primary key values of all new rows inserted into the table.
+** It also records the original primary key and other column values of any
+** deleted or updated rows. For each unique primary key value, data is only
+** recorded once - the first time a row with said primary key is inserted,
+** updated or deleted in the lifetime of the session.
+**
+** There is one exception to the previous paragraph: when a row is inserted,
+** updated or deleted, if one or more of its primary key columns contain a
+** NULL value, no record of the change is made.
+**
+** The session object therefore accumulates two types of records - those
+** that consist of primary key values only (created when the user inserts
+** a new record) and those that consist of the primary key values and the
+** original values of other table columns (created when the users deletes
+** or updates a record).
+**
+** When this function is called, the requested changeset is created using
+** both the accumulated records and the current contents of the database
+** file. Specifically:
+**
+** <ul>
+**   <li> For each record generated by an insert, the database is queried
+**        for a row with a matching primary key. If one is found, an INSERT
+**        change is added to the changeset. If no such row is found, no change 
+**        is added to the changeset.
+**
+**   <li> For each record generated by an update or delete, the database is 
+**        queried for a row with a matching primary key. If such a row is
+**        found and one or more of the non-primary key fields have been
+**        modified from their original values, an UPDATE change is added to 
+**        the changeset. Or, if no such row is found in the table, a DELETE 
+**        change is added to the changeset. If there is a row with a matching
+**        primary key in the database, but all fields contain their original
+**        values, no change is added to the changeset.
+** </ul>
+**
+** This means, amongst other things, that if a row is inserted and then later
+** deleted while a session object is active, neither the insert nor the delete
+** will be present in the changeset. Or if a row is deleted and then later a 
+** row with the same primary key values inserted while a session object is
+** active, the resulting changeset will contain an UPDATE change instead of
+** a DELETE and an INSERT.
+**
+** When a session object is disabled (see the [sqlite3session_enable()] API),
+** it does not accumulate records when rows are inserted, updated or deleted.
+** This may appear to have some counter-intuitive effects if a single row
+** is written to more than once during a session. For example, if a row
+** is inserted while a session object is enabled, then later deleted while 
+** the same session object is disabled, no INSERT record will appear in the
+** changeset, even though the delete took place while the session was disabled.
+** Or, if one field of a row is updated while a session is disabled, and 
+** another field of the same row is updated while the session is enabled, the
+** resulting changeset will contain an UPDATE change that updates both fields.
+*/
+int sqlite3session_changeset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
+  void **ppChangeset              /* OUT: Buffer containing changeset */
+);
+
+/*
+** CAPI3REF: Load The Difference Between Tables Into A Session 
+**
+** If it is not already attached to the session object passed as the first
+** argument, this function attaches table zTbl in the same manner as the
+** [sqlite3session_attach()] function. If zTbl does not exist, or if it
+** does not have a primary key, this function is a no-op (but does not return
+** an error).
+**
+** Argument zFromDb must be the name of a database ("main", "temp" etc.)
+** attached to the same database handle as the session object that contains 
+** a table compatible with the table attached to the session by this function.
+** A table is considered compatible if it:
+**
+** <ul>
+**   <li> Has the same name,
+**   <li> Has the same set of columns declared in the same order, and
+**   <li> Has the same PRIMARY KEY definition.
+** </ul>
+**
+** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
+** are compatible but do not have any PRIMARY KEY columns, it is not an error
+** but no changes are added to the session object. As with other session
+** APIs, tables without PRIMARY KEYs are simply ignored.
+**
+** This function adds a set of changes to the session object that could be
+** used to update the table in database zFrom (call this the "from-table") 
+** so that its content is the same as the table attached to the session 
+** object (call this the "to-table"). Specifically:
+**
+** <ul>
+**   <li> For each row (primary key) that exists in the to-table but not in 
+**     the from-table, an INSERT record is added to the session object.
+**
+**   <li> For each row (primary key) that exists in the to-table but not in 
+**     the from-table, a DELETE record is added to the session object.
+**
+**   <li> For each row (primary key) that exists in both tables, but features 
+**     different in each, an UPDATE record is added to the session.
+** </ul>
+**
+** To clarify, if this function is called and then a changeset constructed
+** using [sqlite3session_changeset()], then after applying that changeset to 
+** database zFrom the contents of the two compatible tables would be 
+** identical.
+**
+** It an error if database zFrom does not exist or does not contain the
+** required compatible table.
+**
+** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite
+** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
+** may be set to point to a buffer containing an English language error 
+** message. It is the responsibility of the caller to free this buffer using
+** sqlite3_free().
+*/
+int sqlite3session_diff(
+  sqlite3_session *pSession,
+  const char *zFromDb,
+  const char *zTbl,
+  char **pzErrMsg
+);
+
+
+/*
+** CAPI3REF: Generate A Patchset From A Session Object
+**
+** The differences between a patchset and a changeset are that:
+**
+** <ul>
+**   <li> DELETE records consist of the primary key fields only. The 
+**        original values of other fields are omitted.
+**   <li> The original values of any modified fields are omitted from 
+**        UPDATE records.
+** </ul>
+**
+** A patchset blob may be used with up to date versions of all 
+** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), 
+** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
+** attempting to use a patchset blob with old versions of the
+** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. 
+**
+** Because the non-primary key "old.*" fields are omitted, no 
+** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
+** is passed to the sqlite3changeset_apply() API. Other conflict types work
+** in the same way as for changesets.
+**
+** Changes within a patchset are ordered in the same way as for changesets
+** generated by the sqlite3session_changeset() function (i.e. all changes for
+** a single table are grouped together, tables appear in the order in which
+** they were attached to the session object).
+*/
+int sqlite3session_patchset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
+  void **ppPatchset               /* OUT: Buffer containing changeset */
+);
+
+/*
+** CAPI3REF: Test if a changeset has recorded any changes.
+**
+** Return non-zero if no changes to attached tables have been recorded by 
+** the session object passed as the first argument. Otherwise, if one or 
+** more changes have been recorded, return zero.
+**
+** Even if this function returns zero, it is possible that calling
+** [sqlite3session_changeset()] on the session handle may still return a
+** changeset that contains no changes. This can happen when a row in 
+** an attached table is modified and then later on the original values 
+** are restored. However, if this function returns non-zero, then it is
+** guaranteed that a call to sqlite3session_changeset() will return a 
+** changeset containing zero changes.
+*/
+int sqlite3session_isempty(sqlite3_session *pSession);
+
+/*
+** CAPI3REF: Create An Iterator To Traverse A Changeset 
+**
+** Create an iterator used to iterate through the contents of a changeset.
+** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+** is returned. Otherwise, if an error occurs, *pp is set to zero and an
+** SQLite error code is returned.
+**
+** The following functions can be used to advance and query a changeset 
+** iterator created by this function:
+**
+** <ul>
+**   <li> [sqlite3changeset_next()]
+**   <li> [sqlite3changeset_op()]
+**   <li> [sqlite3changeset_new()]
+**   <li> [sqlite3changeset_old()]
+** </ul>
+**
+** It is the responsibility of the caller to eventually destroy the iterator
+** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
+** changeset (pChangeset) must remain valid until after the iterator is
+** destroyed.
+**
+** Assuming the changeset blob was created by one of the
+** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
+** [sqlite3changeset_invert()] functions, all changes within the changeset 
+** that apply to a single table are grouped together. This means that when 
+** an application iterates through a changeset using an iterator created by 
+** this function, all changes that relate to a single table are visted 
+** consecutively. There is no chance that the iterator will visit a change 
+** the applies to table X, then one for table Y, and then later on visit 
+** another change for table X.
+*/
+int sqlite3changeset_start(
+  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+  int nChangeset,                 /* Size of changeset blob in bytes */
+  void *pChangeset                /* Pointer to blob containing changeset */
+);
+
+
+/*
+** CAPI3REF: Advance A Changeset Iterator
+**
+** This function may only be used with iterators created by function
+** [sqlite3changeset_start()]. If it is called on an iterator passed to
+** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
+** is returned and the call has no effect.
+**
+** Immediately after an iterator is created by sqlite3changeset_start(), it
+** does not point to any change in the changeset. Assuming the changeset
+** is not empty, the first call to this function advances the iterator to
+** point to the first change in the changeset. Each subsequent call advances
+** the iterator to point to the next change in the changeset (if any). If
+** no error occurs and the iterator points to a valid change after a call
+** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. 
+** Otherwise, if all changes in the changeset have already been visited,
+** SQLITE_DONE is returned.
+**
+** If an error occurs, an SQLite error code is returned. Possible error 
+** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or 
+** SQLITE_NOMEM.
+*/
+int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
+** is not the case, this function returns [SQLITE_MISUSE].
+**
+** If argument pzTab is not NULL, then *pzTab is set to point to a
+** nul-terminated utf-8 encoded string containing the name of the table
+** affected by the current change. The buffer remains valid until either
+** sqlite3changeset_next() is called on the iterator or until the 
+** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
+** set to the number of columns in the table affected by the change. If
+** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** is an indirect change, or false (0) otherwise. See the documentation for
+** [sqlite3session_indirect()] for a description of direct and indirect
+** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
+** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the 
+** type of change that the iterator currently points to.
+**
+** If no error occurs, SQLITE_OK is returned. If an error does occur, an
+** SQLite error code is returned. The values of the output variables may not
+** be trusted in this case.
+*/
+int sqlite3changeset_op(
+  sqlite3_changeset_iter *pIter,  /* Iterator object */
+  const char **pzTab,             /* OUT: Pointer to table name */
+  int *pnCol,                     /* OUT: Number of columns in table */
+  int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
+  int *pbIndirect                 /* OUT: True for an 'indirect' change */
+);
+
+/*
+** CAPI3REF: Obtain The Primary Key Definition Of A Table
+**
+** For each modified table, a changeset includes the following:
+**
+** <ul>
+**   <li> The number of columns in the table, and
+**   <li> Which of those columns make up the tables PRIMARY KEY.
+** </ul>
+**
+** This function is used to find which columns comprise the PRIMARY KEY of
+** the table modified by the change that iterator pIter currently points to.
+** If successful, *pabPK is set to point to an array of nCol entries, where
+** nCol is the number of columns in the table. Elements of *pabPK are set to
+** 0x01 if the corresponding column is part of the tables primary key, or
+** 0x00 if it is not.
+**
+** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
+** in the table.
+**
+** If this function is called when the iterator does not point to a valid
+** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
+** SQLITE_OK is returned and the output variables populated as described
+** above.
+*/
+int sqlite3changeset_pk(
+  sqlite3_changeset_iter *pIter,  /* Iterator object */
+  unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
+  int *pnCol                      /* OUT: Number of entries in output array */
+);
+
+/*
+** CAPI3REF: Obtain old.* Values From A Changeset Iterator
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** original row values stored as part of the UPDATE or DELETE change and
+** returns SQLITE_OK. The name of the function comes from the fact that this 
+** is similar to the "old.*" columns available to update or delete triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+int sqlite3changeset_old(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain new.* Values From A Changeset Iterator
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** new row values stored as part of the UPDATE or INSERT change and
+** returns SQLITE_OK. If the change is an UPDATE and does not include
+** a new value for the requested column, *ppValue is set to NULL and 
+** SQLITE_OK returned. The name of the function comes from the fact that 
+** this is similar to the "new.*" columns available to update or delete 
+** triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+int sqlite3changeset_new(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
+**
+** This function should only be used with iterator objects passed to a
+** conflict-handler callback by [sqlite3changeset_apply()] with either
+** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
+** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
+** is set to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the 
+** "conflicting row" associated with the current conflict-handler callback
+** and returns SQLITE_OK.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+int sqlite3changeset_conflict(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: Value from conflicting row */
+);
+
+/*
+** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
+**
+** This function may only be called with an iterator passed to an
+** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+** it sets the output variable to the total number of known foreign key
+** violations in the destination database and returns SQLITE_OK.
+**
+** In all other cases this function returns SQLITE_MISUSE.
+*/
+int sqlite3changeset_fk_conflicts(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int *pnOut                      /* OUT: Number of FK violations */
+);
+
+
+/*
+** CAPI3REF: Finalize A Changeset Iterator
+**
+** This function is used to finalize an iterator allocated with
+** [sqlite3changeset_start()].
+**
+** This function should only be called on iterators created using the
+** [sqlite3changeset_start()] function. If an application calls this
+** function with an iterator passed to a conflict-handler by
+** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
+** call has no effect.
+**
+** If an error was encountered within a call to an sqlite3changeset_xxx()
+** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an 
+** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
+** to that error is returned by this function. Otherwise, SQLITE_OK is
+** returned. This is to allow the following pattern (pseudo-code):
+**
+**   sqlite3changeset_start();
+**   while( SQLITE_ROW==sqlite3changeset_next() ){
+**     // Do something with change.
+**   }
+**   rc = sqlite3changeset_finalize();
+**   if( rc!=SQLITE_OK ){
+**     // An error has occurred 
+**   }
+*/
+int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Invert A Changeset
+**
+** This function is used to "invert" a changeset object. Applying an inverted
+** changeset to a database reverses the effects of applying the uninverted
+** changeset. Specifically:
+**
+** <ul>
+**   <li> Each DELETE change is changed to an INSERT, and
+**   <li> Each INSERT change is changed to a DELETE, and
+**   <li> For each UPDATE change, the old.* and new.* values are exchanged.
+** </ul>
+**
+** This function does not change the order in which changes appear within
+** the changeset. It merely reverses the sense of each individual change.
+**
+** If successful, a pointer to a buffer containing the inverted changeset
+** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
+** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
+** zeroed and an SQLite error code returned.
+**
+** It is the responsibility of the caller to eventually call sqlite3_free()
+** on the *ppOut pointer to free the buffer allocation following a successful 
+** call to this function.
+**
+** WARNING/TODO: This function currently assumes that the input is a valid
+** changeset. If it is not, the results are undefined.
+*/
+int sqlite3changeset_invert(
+  int nIn, const void *pIn,       /* Input changeset */
+  int *pnOut, void **ppOut        /* OUT: Inverse of input */
+);
+
+/*
+** CAPI3REF: Concatenate Two Changeset Objects
+**
+** This function is used to concatenate two changesets, A and B, into a 
+** single changeset. The result is a changeset equivalent to applying
+** changeset A followed by changeset B. 
+**
+** This function combines the two input changesets using an 
+** sqlite3_changegroup object. Calling it produces similar results as the
+** following code fragment:
+**
+**   sqlite3_changegroup *pGrp;
+**   rc = sqlite3_changegroup_new(&pGrp);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
+**   if( rc==SQLITE_OK ){
+**     rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
+**   }else{
+**     *ppOut = 0;
+**     *pnOut = 0;
+**   }
+**
+** Refer to the sqlite3_changegroup documentation below for details.
+*/
+int sqlite3changeset_concat(
+  int nA,                         /* Number of bytes in buffer pA */
+  void *pA,                       /* Pointer to buffer containing changeset A */
+  int nB,                         /* Number of bytes in buffer pB */
+  void *pB,                       /* Pointer to buffer containing changeset B */
+  int *pnOut,                     /* OUT: Number of bytes in output changeset */
+  void **ppOut                    /* OUT: Buffer containing output changeset */
+);
+
+
+/*
+** Changegroup handle.
+*/
+typedef struct sqlite3_changegroup sqlite3_changegroup;
+
+/*
+** CAPI3REF: Combine two or more changesets into a single changeset.
+**
+** An sqlite3_changegroup object is used to combine two or more changesets
+** (or patchsets) into a single changeset (or patchset). A single changegroup
+** object may combine changesets or patchsets, but not both. The output is
+** always in the same format as the input.
+**
+** If successful, this function returns SQLITE_OK and populates (*pp) with
+** a pointer to a new sqlite3_changegroup object before returning. The caller
+** should eventually free the returned object using a call to 
+** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
+** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
+**
+** The usual usage pattern for an sqlite3_changegroup object is as follows:
+**
+** <ul>
+**   <li> It is created using a call to sqlite3changegroup_new().
+**
+**   <li> Zero or more changesets (or patchsets) are added to the object
+**        by calling sqlite3changegroup_add().
+**
+**   <li> The result of combining all input changesets together is obtained 
+**        by the application via a call to sqlite3changegroup_output().
+**
+**   <li> The object is deleted using a call to sqlite3changegroup_delete().
+** </ul>
+**
+** Any number of calls to add() and output() may be made between the calls to
+** new() and delete(), and in any order.
+**
+** As well as the regular sqlite3changegroup_add() and 
+** sqlite3changegroup_output() functions, also available are the streaming
+** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
+*/
+int sqlite3changegroup_new(sqlite3_changegroup **pp);
+
+/*
+** Add all changes within the changeset (or patchset) in buffer pData (size
+** nData bytes) to the changegroup. 
+**
+** If the buffer contains a patchset, then all prior calls to this function
+** on the same changegroup object must also have specified patchsets. Or, if
+** the buffer contains a changeset, so must have the earlier calls to this
+** function. Otherwise, SQLITE_ERROR is returned and no changes are added
+** to the changegroup.
+**
+** Rows within the changeset and changegroup are identified by the values in
+** their PRIMARY KEY columns. A change in the changeset is considered to
+** apply to the same row as a change already present in the changegroup if
+** the two rows have the same primary key.
+**
+** Changes to rows that that do not already appear in the changegroup are
+** simply copied into it. Or, if both the new changeset and the changegroup
+** contain changes that apply to a single row, the final contents of the
+** changegroup depends on the type of each change, as follows:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+**   <tr><th style="white-space:pre">Existing Change  </th>
+**       <th style="white-space:pre">New Change       </th>
+**       <th>Output Change
+**   <tr><td>INSERT <td>INSERT <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>INSERT <td>UPDATE <td>
+**       The INSERT change remains in the changegroup. The values in the 
+**       INSERT change are modified as if the row was inserted by the
+**       existing change and then updated according to the new change.
+**   <tr><td>INSERT <td>DELETE <td>
+**       The existing INSERT is removed from the changegroup. The DELETE is
+**       not added.
+**   <tr><td>UPDATE <td>INSERT <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>UPDATE <td>UPDATE <td>
+**       The existing UPDATE remains within the changegroup. It is amended 
+**       so that the accompanying values are as if the row was updated once 
+**       by the existing change and then again by the new change.
+**   <tr><td>UPDATE <td>DELETE <td>
+**       The existing UPDATE is replaced by the new DELETE within the
+**       changegroup.
+**   <tr><td>DELETE <td>INSERT <td>
+**       If one or more of the column values in the row inserted by the
+**       new change differ from those in the row deleted by the existing 
+**       change, the existing DELETE is replaced by an UPDATE within the
+**       changegroup. Otherwise, if the inserted row is exactly the same 
+**       as the deleted row, the existing DELETE is simply discarded.
+**   <tr><td>DELETE <td>UPDATE <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>DELETE <td>DELETE <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+** </table>
+**
+** If the new changeset contains changes to a table that is already present
+** in the changegroup, then the number of columns and the position of the
+** primary key columns for the table must be consistent. If this is not the
+** case, this function fails with SQLITE_SCHEMA. If the input changeset
+** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
+** returned. Or, if an out-of-memory condition occurs during processing, this
+** function returns SQLITE_NOMEM. In all cases, if an error occurs the
+** final contents of the changegroup is undefined.
+**
+** If no error occurs, SQLITE_OK is returned.
+*/
+int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+
+/*
+** Obtain a buffer containing a changeset (or patchset) representing the
+** current contents of the changegroup. If the inputs to the changegroup
+** were themselves changesets, the output is a changeset. Or, if the
+** inputs were patchsets, the output is also a patchset.
+**
+** As with the output of the sqlite3session_changeset() and
+** sqlite3session_patchset() functions, all changes related to a single
+** table are grouped together in the output of this function. Tables appear
+** in the same order as for the very first changeset added to the changegroup.
+** If the second or subsequent changesets added to the changegroup contain
+** changes for tables that do not appear in the first changeset, they are
+** appended onto the end of the output changeset, again in the order in
+** which they are first encountered.
+**
+** If an error occurs, an SQLite error code is returned and the output
+** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
+** is returned and the output variables are set to the size of and a 
+** pointer to the output buffer, respectively. In this case it is the
+** responsibility of the caller to eventually free the buffer using a
+** call to sqlite3_free().
+*/
+int sqlite3changegroup_output(
+  sqlite3_changegroup*,
+  int *pnData,                    /* OUT: Size of output buffer in bytes */
+  void **ppData                   /* OUT: Pointer to output buffer */
+);
+
+/*
+** Delete a changegroup object.
+*/
+void sqlite3changegroup_delete(sqlite3_changegroup*);
+
+/*
+** CAPI3REF: Apply A Changeset To A Database
+**
+** Apply a changeset to a database. This function attempts to update the
+** "main" database attached to handle db with the changes found in the
+** changeset passed via the second and third arguments.
+**
+** The fourth argument (xFilter) passed to this function is the "filter
+** callback". If it is not NULL, then for each table affected by at least one
+** change in the changeset, the filter callback is invoked with
+** the table name as the second argument, and a copy of the context pointer
+** passed as the sixth argument to this function as the first. If the "filter
+** callback" returns zero, then no attempt is made to apply any changes to 
+** the table. Otherwise, if the return value is non-zero or the xFilter
+** argument to this function is NULL, all changes related to the table are
+** attempted.
+**
+** For each table that is not excluded by the filter callback, this function 
+** tests that the target database contains a compatible table. A table is 
+** considered compatible if all of the following are true:
+**
+** <ul>
+**   <li> The table has the same name as the name recorded in the 
+**        changeset, and
+**   <li> The table has the same number of columns as recorded in the 
+**        changeset, and
+**   <li> The table has primary key columns in the same position as 
+**        recorded in the changeset.
+** </ul>
+**
+** If there is no compatible table, it is not an error, but none of the
+** changes associated with the table are applied. A warning message is issued
+** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
+** one such warning is issued for each table in the changeset.
+**
+** For each change for which there is a compatible table, an attempt is made 
+** to modify the table contents according to the UPDATE, INSERT or DELETE 
+** change. If a change cannot be applied cleanly, the conflict handler 
+** function passed as the fifth argument to sqlite3changeset_apply() may be 
+** invoked. A description of exactly when the conflict handler is invoked for 
+** each type of change is below.
+**
+** Unlike the xFilter argument, xConflict may not be passed NULL. The results
+** of passing anything other than a valid function pointer as the xConflict
+** argument are undefined.
+**
+** Each time the conflict handler function is invoked, it must return one
+** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or 
+** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
+** if the second argument passed to the conflict handler is either
+** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
+** returns an illegal value, any changes already made are rolled back and
+** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different 
+** actions are taken by sqlite3changeset_apply() depending on the value
+** returned by each invocation of the conflict-handler function. Refer to
+** the documentation for the three 
+** [SQLITE_CHANGESET_OMIT|available return values] for details.
+**
+** <dl>
+** <dt>DELETE Changes<dd>
+**   For each DELETE change, this function checks if the target database 
+**   contains a row with the same primary key value (or values) as the 
+**   original row values stored in the changeset. If it does, and the values 
+**   stored in all non-primary key columns also match the values stored in 
+**   the changeset the row is deleted from the target database.
+**
+**   If a row with matching primary key values is found, but one or more of
+**   the non-primary key fields contains a value different from the original
+**   row value stored in the changeset, the conflict-handler function is
+**   invoked with [SQLITE_CHANGESET_DATA] as the second argument.
+**
+**   If no row with matching primary key values is found in the database,
+**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+**   passed as the second argument.
+**
+**   If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
+**   (which can only happen if a foreign key constraint is violated), the
+**   conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
+**   passed as the second argument. This includes the case where the DELETE
+**   operation is attempted because an earlier call to the conflict handler
+**   function returned [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>INSERT Changes<dd>
+**   For each INSERT change, an attempt is made to insert the new row into
+**   the database.
+**
+**   If the attempt to insert the row fails because the database already 
+**   contains a row with the same primary key values, the conflict handler
+**   function is invoked with the second argument set to 
+**   [SQLITE_CHANGESET_CONFLICT].
+**
+**   If the attempt to insert the row fails because of some other constraint
+**   violation (e.g. NOT NULL or UNIQUE), the conflict handler function is 
+**   invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
+**   This includes the case where the INSERT operation is re-attempted because 
+**   an earlier call to the conflict handler function returned 
+**   [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>UPDATE Changes<dd>
+**   For each UPDATE change, this function checks if the target database 
+**   contains a row with the same primary key value (or values) as the 
+**   original row values stored in the changeset. If it does, and the values 
+**   stored in all non-primary key columns also match the values stored in 
+**   the changeset the row is updated within the target database.
+**
+**   If a row with matching primary key values is found, but one or more of
+**   the non-primary key fields contains a value different from an original
+**   row value stored in the changeset, the conflict-handler function is
+**   invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
+**   UPDATE changes only contain values for non-primary key fields that are
+**   to be modified, only those fields need to match the original values to
+**   avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
+**
+**   If no row with matching primary key values is found in the database,
+**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+**   passed as the second argument.
+**
+**   If the UPDATE operation is attempted, but SQLite returns 
+**   SQLITE_CONSTRAINT, the conflict-handler function is invoked with 
+**   [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
+**   This includes the case where the UPDATE operation is attempted after 
+**   an earlier call to the conflict handler function returned
+**   [SQLITE_CHANGESET_REPLACE].  
+** </dl>
+**
+** It is safe to execute SQL statements, including those that write to the
+** table that the callback related to, from within the xConflict callback.
+** This can be used to further customize the applications conflict
+** resolution strategy.
+**
+** All changes made by this function are enclosed in a savepoint transaction.
+** If any other error (aside from a constraint failure when attempting to
+** write to the target database) occurs, then the savepoint transaction is
+** rolled back, restoring the target database to its original state, and an 
+** SQLite error code returned.
+*/
+int sqlite3changeset_apply(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int nChangeset,                 /* Size of changeset in bytes */
+  void *pChangeset,               /* Changeset blob */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+);
+
+/* 
+** CAPI3REF: Constants Passed To The Conflict Handler
+**
+** Values that may be passed as the second argument to a conflict-handler.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_DATA<dd>
+**   The conflict handler is invoked with CHANGESET_DATA as the second argument
+**   when processing a DELETE or UPDATE change if a row with the required
+**   PRIMARY KEY fields is present in the database, but one or more other 
+**   (non primary-key) fields modified by the update do not contain the 
+**   expected "before" values.
+** 
+**   The conflicting row, in this case, is the database row with the matching
+**   primary key.
+** 
+** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
+**   The conflict handler is invoked with CHANGESET_NOTFOUND as the second
+**   argument when processing a DELETE or UPDATE change if a row with the
+**   required PRIMARY KEY fields is not present in the database.
+** 
+**   There is no conflicting row in this case. The results of invoking the
+**   sqlite3changeset_conflict() API are undefined.
+** 
+** <dt>SQLITE_CHANGESET_CONFLICT<dd>
+**   CHANGESET_CONFLICT is passed as the second argument to the conflict
+**   handler while processing an INSERT change if the operation would result 
+**   in duplicate primary key values.
+** 
+**   The conflicting row in this case is the database row with the matching
+**   primary key.
+**
+** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
+**   If foreign key handling is enabled, and applying a changeset leaves the
+**   database in a state containing foreign key violations, the conflict 
+**   handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
+**   exactly once before the changeset is committed. If the conflict handler
+**   returns CHANGESET_OMIT, the changes, including those that caused the
+**   foreign key constraint violation, are committed. Or, if it returns
+**   CHANGESET_ABORT, the changeset is rolled back.
+**
+**   No current or conflicting row information is provided. The only function
+**   it is possible to call on the supplied sqlite3_changeset_iter handle
+**   is sqlite3changeset_fk_conflicts().
+** 
+** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
+**   If any other constraint violation occurs while applying a change (i.e. 
+**   a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is 
+**   invoked with CHANGESET_CONSTRAINT as the second argument.
+** 
+**   There is no conflicting row in this case. The results of invoking the
+**   sqlite3changeset_conflict() API are undefined.
+**
+** </dl>
+*/
+#define SQLITE_CHANGESET_DATA        1
+#define SQLITE_CHANGESET_NOTFOUND    2
+#define SQLITE_CHANGESET_CONFLICT    3
+#define SQLITE_CHANGESET_CONSTRAINT  4
+#define SQLITE_CHANGESET_FOREIGN_KEY 5
+
+/* 
+** CAPI3REF: Constants Returned By The Conflict Handler
+**
+** A conflict handler callback must return one of the following three values.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_OMIT<dd>
+**   If a conflict handler returns this value no special action is taken. The
+**   change that caused the conflict is not applied. The session module 
+**   continues to the next change in the changeset.
+**
+** <dt>SQLITE_CHANGESET_REPLACE<dd>
+**   This value may only be returned if the second argument to the conflict
+**   handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
+**   is not the case, any changes applied so far are rolled back and the 
+**   call to sqlite3changeset_apply() returns SQLITE_MISUSE.
+**
+**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
+**   handler, then the conflicting row is either updated or deleted, depending
+**   on the type of change.
+**
+**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
+**   handler, then the conflicting row is removed from the database and a
+**   second attempt to apply the change is made. If this second attempt fails,
+**   the original row is restored to the database before continuing.
+**
+** <dt>SQLITE_CHANGESET_ABORT<dd>
+**   If this value is returned, any changes applied so far are rolled back 
+**   and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
+** </dl>
+*/
+#define SQLITE_CHANGESET_OMIT       0
+#define SQLITE_CHANGESET_REPLACE    1
+#define SQLITE_CHANGESET_ABORT      2
+
+/*
+** CAPI3REF: Streaming Versions of API functions.
+**
+** The six streaming API xxx_strm() functions serve similar purposes to the 
+** corresponding non-streaming API functions:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+**   <tr><th>Streaming function<th>Non-streaming equivalent</th>
+**   <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] 
+**   <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] 
+**   <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] 
+**   <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] 
+**   <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] 
+**   <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] 
+** </table>
+**
+** Non-streaming functions that accept changesets (or patchsets) as input
+** require that the entire changeset be stored in a single buffer in memory. 
+** Similarly, those that return a changeset or patchset do so by returning 
+** a pointer to a single large buffer allocated using sqlite3_malloc(). 
+** Normally this is convenient. However, if an application running in a 
+** low-memory environment is required to handle very large changesets, the
+** large contiguous memory allocations required can become onerous.
+**
+** In order to avoid this problem, instead of a single large buffer, input
+** is passed to a streaming API functions by way of a callback function that
+** the sessions module invokes to incrementally request input data as it is
+** required. In all cases, a pair of API function parameters such as
+**
+**  <pre>
+**  &nbsp;     int nChangeset,
+**  &nbsp;     void *pChangeset,
+**  </pre>
+**
+** Is replaced by:
+**
+**  <pre>
+**  &nbsp;     int (*xInput)(void *pIn, void *pData, int *pnData),
+**  &nbsp;     void *pIn,
+**  </pre>
+**
+** Each time the xInput callback is invoked by the sessions module, the first
+** argument passed is a copy of the supplied pIn context pointer. The second 
+** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no 
+** error occurs the xInput method should copy up to (*pnData) bytes of data 
+** into the buffer and set (*pnData) to the actual number of bytes copied 
+** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) 
+** should be set to zero to indicate this. Or, if an error occurs, an SQLite 
+** error code should be returned. In all cases, if an xInput callback returns
+** an error, all processing is abandoned and the streaming API function
+** returns a copy of the error code to the caller.
+**
+** In the case of sqlite3changeset_start_strm(), the xInput callback may be
+** invoked by the sessions module at any point during the lifetime of the
+** iterator. If such an xInput callback returns an error, the iterator enters
+** an error state, whereby all subsequent calls to iterator functions 
+** immediately fail with the same error code as returned by xInput.
+**
+** Similarly, streaming API functions that return changesets (or patchsets)
+** return them in chunks by way of a callback function instead of via a
+** pointer to a single large buffer. In this case, a pair of parameters such
+** as:
+**
+**  <pre>
+**  &nbsp;     int *pnChangeset,
+**  &nbsp;     void **ppChangeset,
+**  </pre>
+**
+** Is replaced by:
+**
+**  <pre>
+**  &nbsp;     int (*xOutput)(void *pOut, const void *pData, int nData),
+**  &nbsp;     void *pOut
+**  </pre>
+**
+** The xOutput callback is invoked zero or more times to return data to
+** the application. The first parameter passed to each call is a copy of the
+** pOut pointer supplied by the application. The second parameter, pData,
+** points to a buffer nData bytes in size containing the chunk of output
+** data being returned. If the xOutput callback successfully processes the
+** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
+** it should return some other SQLite error code. In this case processing
+** is immediately abandoned and the streaming API function returns a copy
+** of the xOutput error code to the application.
+**
+** The sessions module never invokes an xOutput callback with the third 
+** parameter set to a value less than or equal to zero. Other than this,
+** no guarantees are made as to the size of the chunks of data returned.
+*/
+int sqlite3changeset_apply_strm(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+  void *pIn,                                          /* First arg for xInput */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+);
+int sqlite3changeset_concat_strm(
+  int (*xInputA)(void *pIn, void *pData, int *pnData),
+  void *pInA,
+  int (*xInputB)(void *pIn, void *pData, int *pnData),
+  void *pInB,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3changeset_invert_strm(
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3changeset_start_strm(
+  sqlite3_changeset_iter **pp,
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn
+);
+int sqlite3session_changeset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3session_patchset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+int sqlite3changegroup_add_strm(sqlite3_changegroup*, 
+    int (*xInput)(void *pIn, void *pData, int *pnData),
+    void *pIn
+);
+int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+    int (*xOutput)(void *pOut, const void *pData, int nData), 
+    void *pOut
+);
+
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
+
+/******** End of sqlite3session.h *********/
+/******** Begin file fts5.h *********/
 /*
 ** 2014 May 31
 **
@@ -8177,11 +9674,13 @@ struct Fts5PhraseIter {
 **       ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
 **
 **   with $p set to a phrase equivalent to the phrase iPhrase of the
-**   current query is executed. For each row visited, the callback function
-**   passed as the fourth argument is invoked. The context and API objects 
-**   passed to the callback function may be used to access the properties of
-**   each matched row. Invoking Api.xUserData() returns a copy of the pointer
-**   passed as the third argument to pUserData.
+**   current query is executed. Any column filter that applies to
+**   phrase iPhrase of the current query is included in $p. For each 
+**   row visited, the callback function passed as the fourth argument 
+**   is invoked. The context and API objects passed to the callback 
+**   function may be used to access the properties of each matched row.
+**   Invoking Api.xUserData() returns a copy of the pointer passed as 
+**   the third argument to pUserData.
 **
 **   If the callback function returns any value other than SQLITE_OK, the
 **   query is abandoned and the xQueryPhrase function returns immediately.
@@ -8611,3 +10110,4 @@ struct fts5_api {
 #endif /* _FTS5_H */
 
 
+/******** End of fts5.h *********/
@@ -279,6 +279,8 @@ struct sqlite3_api_routines {
   int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
   int (*strlike)(const char*,const char*,unsigned int);
   int (*db_cacheflush)(sqlite3*);
+  /* Version 3.12.0 and later */
+  int (*system_errno)(sqlite3*);
 };
 
 /*
@@ -540,6 +542,8 @@ struct sqlite3_api_routines {
 #define sqlite3_status64               sqlite3_api->status64
 #define sqlite3_strlike                sqlite3_api->strlike
 #define sqlite3_db_cacheflush          sqlite3_api->db_cacheflush
+/* Version 3.12.0 and later */
+#define sqlite3_system_errno           sqlite3_api->system_errno
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
similarity index 98%
rename from pkgs/sqlite3.11.0/configure
rename to pkgs/sqlite3.13.0/configure
index f352bd1..fa61e35 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.11.0.
+# Generated by GNU Autoconf 2.69 for sqlite 3.13.0.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='sqlite'
 PACKAGE_TARNAME='sqlite'
-PACKAGE_VERSION='3.11.0'
-PACKAGE_STRING='sqlite 3.11.0'
+PACKAGE_VERSION='3.13.0'
+PACKAGE_STRING='sqlite 3.13.0'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -652,11 +652,9 @@ EGREP
 GREP
 RANLIB
 SET_MAKE
-INSTALL_LIBRARY
 INSTALL_SCRIPT
 INSTALL_PROGRAM
 INSTALL_DATA
-INSTALL_DATA_DIR
 INSTALL
 CPP
 TCL_SHLIB_LD_LIBS
@@ -1294,7 +1292,7 @@ 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 sqlite 3.11.0 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.13.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1355,7 +1353,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of sqlite 3.11.0:";;
+     short | recursive ) echo "Configuration of sqlite 3.13.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1457,7 +1455,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-sqlite configure 3.11.0
+sqlite configure 3.13.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1868,7 +1866,7 @@ 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 sqlite $as_me 3.11.0, which was
+It was created by sqlite $as_me 3.13.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2232,7 +2230,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 $as_echo_n "checking for correct TEA configuration... " >&6; }
     if test x"${PACKAGE_NAME}" = x ; then
        as_fn_error $? "
-The PACKAGE_NAME variable must be defined by your TEA configure.ac" "$LINENO" 5
+The PACKAGE_NAME variable must be defined by your TEA configure.in" "$LINENO" 5
     fi
     if test x"3.9" = x ; then
        as_fn_error $? "
@@ -2270,7 +2268,7 @@ do
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
   if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CYGPATH="cygpath -m"
+    ac_cv_prog_CYGPATH="cygpath -w"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -2295,8 +2293,9 @@ fi
            TEA_PLATFORM="windows"
            ;;
        *CYGWIN_*)
+           CYGPATH=echo
            EXEEXT=".exe"
-           # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG
+           # TEA_PLATFORM is determined later in LOAD_TCLCONFIG
            ;;
        *)
            CYGPATH=echo
@@ -3404,51 +3403,9 @@ main ()
 }
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
-
-           TEA_PLATFORM="unix"
-           CYGPATH=echo
-
+  TEA_PLATFORM="unix"
 else
-
-           TEA_PLATFORM="windows"
-           # Extract the first word of "cygpath", so it can be a program name with args.
-set dummy cygpath; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CYGPATH+:} false; then :
-  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CYGPATH="cygpath -m"
-    $as_echo "$as_me:${as_lineno-$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
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
-$as_echo "$CYGPATH" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
+  TEA_PLATFORM="windows"
 
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
@@ -4205,18 +4162,13 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-    INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
-    INSTALL_DATA_DIR='${INSTALL} -d -m 755'
-    INSTALL_DATA='${INSTALL} -m 644'
-    INSTALL_PROGRAM='${INSTALL}'
-    INSTALL_SCRIPT='${INSTALL}'
-    INSTALL_LIBRARY='${INSTALL_DATA}'
-
-
-
+    INSTALL="\$(SHELL) \$(srcdir)/tclconfig/install-sh -c"
 
+    INSTALL_DATA="\${INSTALL} -m 644"
 
+    INSTALL_PROGRAM="\${INSTALL}"
 
+    INSTALL_SCRIPT="\${INSTALL}"
 
 
     #--------------------------------------------------------------------
@@ -5457,6 +5409,10 @@ done
 
 
 
+    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_COLUMN_METADATA=1"
+
+
+
     PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_JSON1=1"
 
 
@@ -5473,11 +5429,11 @@ done
 
 
 
-    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_OMIT_DEPRECATED=1"
+    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_OMIT_BUILTIN_TEST=1"
 
 
 
-    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_OMIT_BUILTIN_TEST=1"
+    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_OMIT_DEPRECATED=1"
 
 
 
@@ -6456,9 +6412,7 @@ fi
     STLIB_LD='${AR} cr'
     LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
     if test "x$SHLIB_VERSION" = x; then :
-  SHLIB_VERSION=""
-else
-  SHLIB_VERSION=".$SHLIB_VERSION"
+  SHLIB_VERSION="1.0"
 fi
     case $system in
        # TEA specific:
@@ -6622,31 +6576,13 @@ $as_echo "found $CELIB_DIR" >&6; }
                else
                    runtime=-MD
                fi
-               case "x`echo \${VisualStudioVersion}`" in
-                   x1[4-9]*)
-                       lflags="${lflags} -nodefaultlib:libucrt.lib"
-
-    vars="ucrt.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
-
-
-                   ;;
-                   *)
-                   ;;
-               esac
 
                 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="${lflags} -nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   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}"
@@ -6698,12 +6634,12 @@ _ACEOF
                    CFLAGS_DEBUG="-nologo -Zi -Od"
                    CFLAGS_OPTIMIZE="-nologo -Ox"
                    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
-                   lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
                    LINKBIN="\"${CEBINROOT}/link.exe\""
 
                else
                    RC="rc"
-                   lflags="${lflags} -nologo"
+                   lflags="-nologo"
                    LINKBIN="link"
                    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
                    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
@@ -7026,7 +6962,6 @@ fi
        CYGWIN_*)
            SHLIB_CFLAGS=""
            SHLIB_LD='${CC} -shared'
-           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a"
            SHLIB_SUFFIX=".dll"
            EXEEXT=".exe"
            do64bit_ok=yes
@@ -7346,14 +7281,7 @@ fi
                LDFLAGS=""
                ;;
            *)
-               case "$arch" in
-               alpha|sparc64)
-                   SHLIB_CFLAGS="-fPIC"
-                   ;;
-               *)
-                   SHLIB_CFLAGS="-fpic"
-                   ;;
-               esac
+               SHLIB_CFLAGS="-fPIC"
                SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
                SHLIB_SUFFIX=".so"
                if test $doRpath = yes; then :
@@ -7361,7 +7289,7 @@ fi
                    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
 fi
                LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
-               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
                LDFLAGS="-Wl,-export-dynamic"
                ;;
            esac
@@ -7409,7 +7337,8 @@ fi
            # This configuration from FreeBSD Ports.
            SHLIB_CFLAGS="-fPIC"
            SHLIB_LD="${CC} -shared"
-           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@"
+           TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$@"
+           TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$@"
            SHLIB_SUFFIX=".so"
            LDFLAGS=""
            if test $doRpath = yes; then :
@@ -7427,9 +7356,9 @@ fi
            case $system in
            FreeBSD-3.*)
                # Version numbers are dot-stripped by system policy.
-               TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
+               TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
                UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
-               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
                TCL_LIB_VERSIONS_OK=nodots
                ;;
            esac
@@ -8686,7 +8615,7 @@ fi
 done
 
 # Check for library functions that SQLite can optionally use.
-for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime flock lstat readlink
+for ac_func in fdatasync usleep strchrnul localtime_r gmtime_r localtime_s malloc_usable_size utime flock readlink lstat pread pread64 pwrite pwrite64 rand_s
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -8855,15 +8784,15 @@ rm -f conftest*
            if test "$GCC" = "yes"; then
                SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
            fi
-           eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
        else
-           eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
            if test "$GCC" = "yes"; then
                PKG_LIB_FILE=lib${PKG_LIB_FILE}
            fi
        fi
        # Some packages build their own stubs libraries
-       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       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
@@ -8877,13 +8806,13 @@ rm -f conftest*
            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_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
            RANLIB=:
        else
-           eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+           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_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       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.
@@ -9496,7 +9425,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by sqlite $as_me 3.11.0, which was
+This file was extended by sqlite $as_me 3.13.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9549,7 +9478,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-sqlite config.status 3.11.0
+sqlite config.status 3.13.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
similarity index 97%
rename from pkgs/sqlite3.11.0/configure.ac
rename to pkgs/sqlite3.13.0/configure.ac
index 592987f..e9c2bb9 100755 (executable)
@@ -19,7 +19,7 @@ dnl   to configure the system for the local environment.
 # so you can encode the package version directly into the source files.
 #-----------------------------------------------------------------------
 
-AC_INIT([sqlite], [3.11.0])
+AC_INIT([sqlite], [3.13.0])
 
 #--------------------------------------------------------------------
 # Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -79,12 +79,13 @@ TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBSTAT_VTAB=1])
 TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3_PARENTHESIS=1])
 TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS4=1])
 TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS5=1])
+TEA_ADD_CFLAGS([-DSQLITE_ENABLE_COLUMN_METADATA=1])
 TEA_ADD_CFLAGS([-DSQLITE_ENABLE_JSON1=1])
 TEA_ADD_CFLAGS([-DSQLITE_3_SUFFIX_ONLY=1])
 TEA_ADD_CFLAGS([-DSQLITE_ENABLE_RTREE=1])
 TEA_ADD_CFLAGS([-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1])
-TEA_ADD_CFLAGS([-DSQLITE_OMIT_DEPRECATED=1])
 TEA_ADD_CFLAGS([-DSQLITE_OMIT_BUILTIN_TEST=1])
+TEA_ADD_CFLAGS([-DSQLITE_OMIT_DEPRECATED=1])
 TEA_ADD_CFLAGS([-DSQLITE_OMIT_LOOKASIDE=1])
 TEA_ADD_CFLAGS([-DSQLITE_SECURE_DELETE=1])
 TEA_ADD_CFLAGS([-DSQLITE_SOUNDEX=1])
@@ -181,7 +182,7 @@ AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
 #AC_CHECK_FUNC(fdatasync, , AC_DEFINE(fdatasync, fsync))
 AC_CHECK_HEADERS([malloc.h])
 # Check for library functions that SQLite can optionally use.
-AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime flock lstat readlink])
+AC_CHECK_FUNCS([fdatasync usleep strchrnul localtime_r gmtime_r localtime_s malloc_usable_size utime flock readlink lstat pread pread64 pwrite pwrite64 rand_s])
 
 AC_FUNC_STRERROR_R
 
similarity index 94%
rename from pkgs/sqlite3.11.0/generic/tclsqlite3.c
rename to pkgs/sqlite3.13.0/generic/tclsqlite3.c
index ed392dc..d2db43d 100644 (file)
@@ -149,6 +149,7 @@ struct SqliteDb {
   char *zNull;               /* Text to substitute for an SQL NULL value */
   SqlFunc *pFunc;            /* List of SQL functions */
   Tcl_Obj *pUpdateHook;      /* Update hook script (if any) */
+  Tcl_Obj *pPreUpdateHook;   /* Pre-update hook script (if any) */
   Tcl_Obj *pRollbackHook;    /* Rollback hook script (if any) */
   Tcl_Obj *pWalHook;         /* WAL hook script (if any) */
   Tcl_Obj *pUnlockNotify;    /* Unlock notify script (if any) */
@@ -532,6 +533,9 @@ static void DbDeleteCmd(void *db){
   if( pDb->pUpdateHook ){
     Tcl_DecrRefCount(pDb->pUpdateHook);
   }
+  if( pDb->pPreUpdateHook ){
+    Tcl_DecrRefCount(pDb->pPreUpdateHook);
+  }
   if( pDb->pRollbackHook ){
     Tcl_DecrRefCount(pDb->pRollbackHook);
   }
@@ -705,6 +709,42 @@ static void DbUnlockNotify(void **apArg, int nArg){
 }
 #endif
 
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Pre-update hook callback.
+*/
+static void DbPreUpdateHandler(
+  void *p, 
+  sqlite3 *db,
+  int op,
+  const char *zDb, 
+  const char *zTbl, 
+  sqlite_int64 iKey1,
+  sqlite_int64 iKey2
+){
+  SqliteDb *pDb = (SqliteDb *)p;
+  Tcl_Obj *pCmd;
+  static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
+
+  assert( (SQLITE_DELETE-1)/9 == 0 );
+  assert( (SQLITE_INSERT-1)/9 == 1 );
+  assert( (SQLITE_UPDATE-1)/9 == 2 );
+  assert( pDb->pPreUpdateHook );
+  assert( db==pDb->db );
+  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
+
+  pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook);
+  Tcl_IncrRefCount(pCmd);
+  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
+  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
+  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
+  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1));
+  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2));
+  Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
+  Tcl_DecrRefCount(pCmd);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
 static void DbUpdateHandler(
   void *p, 
   int op,
@@ -714,14 +754,18 @@ static void DbUpdateHandler(
 ){
   SqliteDb *pDb = (SqliteDb *)p;
   Tcl_Obj *pCmd;
+  static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
+
+  assert( (SQLITE_DELETE-1)/9 == 0 );
+  assert( (SQLITE_INSERT-1)/9 == 1 );
+  assert( (SQLITE_UPDATE-1)/9 == 2 );
 
   assert( pDb->pUpdateHook );
   assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
 
   pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
   Tcl_IncrRefCount(pCmd);
-  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(
-    ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1));
+  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
   Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
   Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
   Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
@@ -1636,6 +1680,46 @@ static int DbEvalNextCmd(
 }
 
 /*
+** This function is used by the implementations of the following database 
+** handle sub-commands:
+**
+**   $db update_hook ?SCRIPT?
+**   $db wal_hook ?SCRIPT?
+**   $db commit_hook ?SCRIPT?
+**   $db preupdate hook ?SCRIPT?
+*/
+static void DbHookCmd(
+  Tcl_Interp *interp,             /* Tcl interpreter */
+  SqliteDb *pDb,                  /* Database handle */
+  Tcl_Obj *pArg,                  /* SCRIPT argument (or NULL) */
+  Tcl_Obj **ppHook                /* Pointer to member of SqliteDb */
+){
+  sqlite3 *db = pDb->db;
+
+  if( *ppHook ){
+    Tcl_SetObjResult(interp, *ppHook);
+    if( pArg ){
+      Tcl_DecrRefCount(*ppHook);
+      *ppHook = 0;
+    }
+  }
+  if( pArg ){
+    assert( !(*ppHook) );
+    if( Tcl_GetCharLength(pArg)>0 ){
+      *ppHook = pArg;
+      Tcl_IncrRefCount(*ppHook);
+    }
+  }
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+  sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb);
+#endif
+  sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
+  sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb);
+  sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb);
+}
+
+/*
 ** The "sqlite" command below creates a new Tcl command for each
 ** connection it opens to an SQLite database.  This routine is invoked
 ** whenever one of those connection-specific commands is executed
@@ -1660,11 +1744,12 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     "errorcode",          "eval",              "exists",
     "function",           "incrblob",          "interrupt",
     "last_insert_rowid",  "nullvalue",         "onecolumn",
-    "profile",            "progress",          "rekey",
-    "restore",            "rollback_hook",     "status",
-    "timeout",            "total_changes",     "trace",
-    "transaction",        "unlock_notify",     "update_hook",
-    "version",            "wal_hook",          0
+    "preupdate",          "profile",           "progress",
+    "rekey",              "restore",           "rollback_hook",
+    "status",             "timeout",           "total_changes",
+    "trace",              "transaction",       "unlock_notify",
+    "update_hook",        "version",           "wal_hook",
+    0                    
   };
   enum DB_enum {
     DB_AUTHORIZER,        DB_BACKUP,           DB_BUSY,
@@ -1674,11 +1759,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     DB_ERRORCODE,         DB_EVAL,             DB_EXISTS,
     DB_FUNCTION,          DB_INCRBLOB,         DB_INTERRUPT,
     DB_LAST_INSERT_ROWID, DB_NULLVALUE,        DB_ONECOLUMN,
-    DB_PROFILE,           DB_PROGRESS,         DB_REKEY,
-    DB_RESTORE,           DB_ROLLBACK_HOOK,    DB_STATUS,
-    DB_TIMEOUT,           DB_TOTAL_CHANGES,    DB_TRACE,
-    DB_TRANSACTION,       DB_UNLOCK_NOTIFY,    DB_UPDATE_HOOK,
-    DB_VERSION,           DB_WAL_HOOK
+    DB_PREUPDATE,         DB_PROFILE,          DB_PROGRESS,
+    DB_REKEY,             DB_RESTORE,          DB_ROLLBACK_HOOK,
+    DB_STATUS,            DB_TIMEOUT,          DB_TOTAL_CHANGES,
+    DB_TRACE,             DB_TRANSACTION,      DB_UNLOCK_NOTIFY,
+    DB_UPDATE_HOOK,       DB_VERSION,          DB_WAL_HOOK,
   };
   /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
 
@@ -2599,7 +2684,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   ** Change the encryption key on the currently open database.
   */
   case DB_REKEY: {
-#ifdef SQLITE_HAS_CODEC
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
     int nKey;
     void *pKey;
 #endif
@@ -2607,7 +2692,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       Tcl_WrongNumArgs(interp, 2, objv, "KEY");
       return TCL_ERROR;
     }
-#ifdef SQLITE_HAS_CODEC
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
     pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
     rc = sqlite3_rekey(pDb->db, pKey, nKey);
     if( rc ){
@@ -2881,6 +2966,90 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   }
 
   /*
+  **    $db preupdate_hook count
+  **    $db preupdate_hook hook ?SCRIPT?
+  **    $db preupdate_hook new INDEX
+  **    $db preupdate_hook old INDEX
+  */
+  case DB_PREUPDATE: {
+#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
+    Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time");
+    rc = TCL_ERROR;
+#else
+    static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0};
+    enum DbPreupdateSubCmd {
+      PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD
+    };
+    int iSub;
+
+    if( objc<3 ){
+      Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?");
+    }
+    if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){
+      return TCL_ERROR;
+    }
+
+    switch( (enum DbPreupdateSubCmd)iSub ){
+      case PRE_COUNT: {
+        int nCol = sqlite3_preupdate_count(pDb->db);
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol));
+        break;
+      }
+
+      case PRE_HOOK: {
+        if( objc>4 ){
+          Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?");
+          return TCL_ERROR;
+        }
+        DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook);
+        break;
+      }
+
+      case PRE_DEPTH: {
+        Tcl_Obj *pRet;
+        if( objc!=3 ){
+          Tcl_WrongNumArgs(interp, 3, objv, "");
+          return TCL_ERROR;
+        }
+        pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db));
+        Tcl_SetObjResult(interp, pRet);
+        break;
+      }
+
+      case PRE_NEW:
+      case PRE_OLD: {
+        int iIdx;
+        sqlite3_value *pValue;
+        if( objc!=4 ){
+          Tcl_WrongNumArgs(interp, 3, objv, "INDEX");
+          return TCL_ERROR;
+        }
+        if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){
+          return TCL_ERROR;
+        }
+
+        if( iSub==PRE_OLD ){
+          rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue);
+        }else{
+          assert( iSub==PRE_NEW );
+          rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue);
+        }
+
+        if( rc==SQLITE_OK ){
+          Tcl_Obj *pObj;
+          pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1);
+          Tcl_SetObjResult(interp, pObj);
+        }else{
+          Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
+          return TCL_ERROR;
+        }
+      }
+    }
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+    break;
+  }
+
+  /*
   **    $db wal_hook ?script?
   **    $db update_hook ?script?
   **    $db rollback_hook ?script?
@@ -2888,42 +3057,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   case DB_WAL_HOOK: 
   case DB_UPDATE_HOOK: 
   case DB_ROLLBACK_HOOK: {
-
     /* set ppHook to point at pUpdateHook or pRollbackHook, depending on 
     ** whether [$db update_hook] or [$db rollback_hook] was invoked.
     */
-    Tcl_Obj **ppHook; 
-    if( choice==DB_UPDATE_HOOK ){
-      ppHook = &pDb->pUpdateHook;
-    }else if( choice==DB_WAL_HOOK ){
-      ppHook = &pDb->pWalHook;
-    }else{
-      ppHook = &pDb->pRollbackHook;
-    }
-
-    if( objc!=2 && objc!=3 ){
+    Tcl_Obj **ppHook = 0; 
+    if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
+    if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
+    if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
+    if( objc>3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
        return TCL_ERROR;
     }
-    if( *ppHook ){
-      Tcl_SetObjResult(interp, *ppHook);
-      if( objc==3 ){
-        Tcl_DecrRefCount(*ppHook);
-        *ppHook = 0;
-      }
-    }
-    if( objc==3 ){
-      assert( !(*ppHook) );
-      if( Tcl_GetCharLength(objv[2])>0 ){
-        *ppHook = objv[2];
-        Tcl_IncrRefCount(*ppHook);
-      }
-    }
-
-    sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
-    sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb);
-    sqlite3_wal_hook(pDb->db,(pDb->pWalHook?DbWalHandler:0),pDb);
 
+    DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook);
     break;
   }
 
@@ -2980,7 +3126,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   const char *zVfs = 0;
   int flags;
   Tcl_DString translatedFilename;
-#ifdef SQLITE_HAS_CODEC
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
   void *pKey = 0;
   int nKey = 0;
 #endif
@@ -3009,7 +3155,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       return TCL_OK;
     }
     if( strcmp(zArg,"-has-codec")==0 ){
-#ifdef SQLITE_HAS_CODEC
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
       Tcl_AppendResult(interp,"1",(char*)0);
 #else
       Tcl_AppendResult(interp,"0",(char*)0);
@@ -3020,7 +3166,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   for(i=3; i+1<objc; i+=2){
     zArg = Tcl_GetString(objv[i]);
     if( strcmp(zArg,"-key")==0 ){
-#ifdef SQLITE_HAS_CODEC
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
       pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
 #endif
     }else if( strcmp(zArg, "-vfs")==0 ){
@@ -3078,7 +3224,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     Tcl_WrongNumArgs(interp, 1, objv, 
       "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
       " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
-#ifdef SQLITE_HAS_CODEC
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
       " ?-key CODECKEY?"
 #endif
     );
@@ -3104,7 +3250,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   }else{
     zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
   }
-#ifdef SQLITE_HAS_CODEC
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
   if( p->db ){
     sqlite3_key(p->db, pKey, nKey);
   }
@@ -3807,8 +3953,12 @@ static void init_all(Tcl_Interp *interp){
     extern int Sqlitemultiplex_Init(Tcl_Interp*);
     extern int SqliteSuperlock_Init(Tcl_Interp*);
     extern int SqlitetestSyscall_Init(Tcl_Interp*);
+#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+    extern int TestSession_Init(Tcl_Interp*);
+#endif
     extern int Fts5tcl_Init(Tcl_Interp *);
     extern int SqliteRbu_Init(Tcl_Interp*);
+    extern int Sqlitetesttcl_Init(Tcl_Interp*);
 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
     extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
 #endif
@@ -3851,8 +4001,12 @@ static void init_all(Tcl_Interp *interp){
     Sqlitemultiplex_Init(interp);
     SqliteSuperlock_Init(interp);
     SqlitetestSyscall_Init(interp);
+#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+    TestSession_Init(interp);
+#endif
     Fts5tcl_Init(interp);
     SqliteRbu_Init(interp);
+    Sqlitetesttcl_Init(interp);
 
 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
     Sqlitetestfts3_Init(interp);
diff --git a/pkgs/thread2.7.3/configure b/pkgs/thread2.7.3/configure
deleted file mode 100755 (executable)
index 621bf8c..0000000
+++ /dev/null
@@ -1,12553 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for thread 2.7.3.
-#
-# 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='thread'
-PACKAGE_TARNAME='thread'
-PACKAGE_VERSION='2.7.3'
-PACKAGE_STRING='thread 2.7.3'
-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_PATCH_LEVEL 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 CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CLEANFILES TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS CPP INSTALL INSTALL_DATA_DIR INSTALL_DATA INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_LIBRARY SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS PKG_SOURCES PKG_OBJECTS TCL_INCLUDES TCL_THREADS SHARED_BUILD AR ac_ct_AR CELIB_DIR RC ac_ct_RC 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 VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCLSH_PROG 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_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 thread 2.7.3 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 thread 2.7.3:";;
-   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-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-naviserver       directory with NaviServer/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>
-  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
-thread configure 2.7.3
-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 thread $as_me 2.7.3, 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.9"
-
-    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.ac" >&5
-echo "$as_me: error:
-The PACKAGE_NAME variable must be defined by your TEA configure.ac" >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-    if test x"3.9" = 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.9" != "${TEA_VERSION}" ; then
-       echo "$as_me:$LINENO: result: warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&5
-echo "${ECHO_T}warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&6
-    else
-       echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5
-echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6
-    fi
-
-    # If the user did not set CFLAGS, set it now to keep macros
-    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
-    if test "${CFLAGS+set}" != "set" ; then
-       CFLAGS=""
-    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 $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"
-           ;;
-       *CYGWIN_*)
-           CYGPATH=echo
-           EXEEXT=".exe"
-           # TEA_PLATFORM is determined later in LOAD_TCLCONFIG
-           ;;
-       *)
-           CYGPATH=echo
-           # Maybe we are cross-compiling....
-           case ${host_alias} in
-               *mingw32*)
-               EXEEXT=".exe"
-               TEA_PLATFORM="windows"
-               ;;
-           *)
-               EXEEXT=""
-               TEA_PLATFORM="unix"
-               ;;
-           esac
-           ;;
-    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
-
-    { echo "$as_me:$LINENO: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&5
-echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
-
-
-
-
-    # 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 "${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` \
-                       `ls -d /usr/lib64 2>/dev/null` \
-                       `ls -d /usr/lib/tcl8.6 2>/dev/null` \
-                       `ls -d /usr/lib/tcl8.5 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. Use --with-tcl to specify a directory containing tclConfig.sh" >&5
-echo "$as_me: error: Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" >&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
-
-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
-
-
-
-    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" | 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}\""
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    echo "$as_me:$LINENO: checking platform" >&5
-echo $ECHO_N "checking platform... $ECHO_C" >&6
-    hold_cc=$CC; CC="$TCL_CC"
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-           #ifdef _WIN32
-               #error win32
-           #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
-  TEA_PLATFORM="unix"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-TEA_PLATFORM="windows"
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-    CC=$hold_cc
-    echo "$as_me:$LINENO: result: $TEA_PLATFORM" >&5
-echo "${ECHO_T}$TEA_PLATFORM" >&6
-
-    # The BUILD_$pkg is to define the correct extern storage class
-    # handling when making this package
-
-cat >>confdefs.h <<_ACEOF
-#define BUILD_${PACKAGE_NAME}
-_ACEOF
-
-    # Do this here as we have fully defined TEA_PLATFORM now
-    if test "${TEA_PLATFORM}" = "windows" ; then
-       EXEEXT=".exe"
-       CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
-    fi
-
-    # TEA specific:
-
-
-
-
-
-
-
-
-if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
-    { { echo "$as_me:$LINENO: error: ${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.4+
-Found config for Tcl ${TCL_VERSION}" >&5
-echo "$as_me: error: ${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.4+
-Found config for Tcl ${TCL_VERSION}" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-if test "${TCL_MINOR_VERSION}" -lt 4 ; then
-    { { echo "$as_me:$LINENO: error: ${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.4+
-Found config for Tcl ${TCL_VERSION}" >&5
-echo "$as_me: error: ${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.4+
-Found config for Tcl ${TCL_VERSION}" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-#--------------------------------------------------------------------
-# 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 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.
-
-    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); }
-
-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
-
-
-    INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
-    INSTALL_DATA_DIR='${INSTALL} -d -m 755'
-    INSTALL_DATA='${INSTALL} -m 644'
-    INSTALL_PROGRAM='${INSTALL}'
-    INSTALL_SCRIPT='${INSTALL}'
-    INSTALL_LIBRARY='${INSTALL_DATA}'
-
-
-
-
-
-
-
-
-    #--------------------------------------------------------------------
-    # 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
-
-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 thread 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 thread 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 thread 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 thread 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 thread 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 thread 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 thread 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 thread 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 thread 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 thread 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
-
-
-#--------------------------------------------------------------------
-# Check if building with optional Gdbm package. This will declare
-# GDBM_CFLAGS and GDBM_LIBS variables.
-#--------------------------------------------------------------------
-
-
-
-# Check whether --with-gdbm or --without-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 NaviServer/AOLserver dir for compilation as NaviServer/AOLserver module.
-# This will declare NS_INCLUDES, NS_LIBS and define NS_AOLSERVER.
-#--------------------------------------------------------------------
-
-
-    echo "$as_me:$LINENO: checking for NaviServer/AOLserver configuration" >&5
-echo $ECHO_N "checking for NaviServer/AOLserver configuration... $ECHO_C" >&6
-
-# Check whether --with-naviserver or --without-naviserver was given.
-if test "${with_naviserver+set}" = set; then
-  withval="$with_naviserver"
-  \
-    with_naviserver=${withval}
-fi;
-
-    if test "${ac_cv_c_naviserver+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-    if test x"${with_naviserver}" != x ; then
-        if test -f "${with_naviserver}/include/ns.h" ; then
-            ac_cv_c_naviserver=`(cd ${with_naviserver}; pwd)`
-        else
-            { { echo "$as_me:$LINENO: error: ${with_naviserver} directory doesn't contain ns.h" >&5
-echo "$as_me: error: ${with_naviserver} directory doesn't contain ns.h" >&2;}
-   { (exit 1); exit 1; }; }
-        fi
-    fi
-
-fi
-
-    if test x"${ac_cv_c_naviserver}" = x ; then
-        echo "$as_me:$LINENO: result: none found" >&5
-echo "${ECHO_T}none found" >&6
-    else
-        NS_DIR=${ac_cv_c_naviserver}
-        echo "$as_me:$LINENO: result: found NaviServer/AOLserver in $NS_DIR" >&5
-echo "${ECHO_T}found NaviServer/AOLserver in $NS_DIR" >&6
-        NS_INCLUDES="-I\"${NS_DIR}/include\""
-        if test "`uname -s`" = Darwin ; then
-            aollibs=`ls ${NS_DIR}/lib/libns* 2>/dev/null`
-            if test x"$aollibs" != x ; then
-                NS_LIBS="-L\"${NS_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/threadNs.c           \
-                 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" \
-                   -a ! -f "${srcdir}/macosx/$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/tclThread.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="${NS_INCLUDES}"
-    for i in $vars; do
-       PKG_INCLUDES="$PKG_INCLUDES $i"
-    done
-
-
-
-    vars="${GDBM_LIBS} ${NS_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" \
-           -a ! -f "${srcdir}/macosx/$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
-
-    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" \
-                   -a ! -f "${srcdir}/macosx/$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" \
-                   -a ! -f "${srcdir}/macosx/$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 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
-           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 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.
-#--------------------------------------------------------------------
-
-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
-
-
-
-
-    # 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
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_HIDDEN 1
-_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
-
-
-    # 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
-       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
-               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
-
-
-    # Require ranlib early so we can override it in special cases below.
-
-
-
-    # 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 and removed some core-only vars.
-
-    do64bit_ok=no
-    # default to '{$LIBS}' and set to "" on per-platform necessary basis
-    SHLIB_LD_LIBS='${LIBS}'
-    # 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=""
-    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
-    if test "$GCC" = yes; then
-
-       CFLAGS_OPTIMIZE=-O2
-       CFLAGS_WARNING="-Wall"
-
-else
-
-       CFLAGS_OPTIMIZE=-O
-       CFLAGS_WARNING=""
-
-fi
-
-    if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}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="${ac_tool_prefix}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
-
-fi
-if test -z "$ac_cv_prog_AR"; then
-  ac_ct_AR=$AR
-  # 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_ac_ct_AR+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_AR"; then
-  ac_cv_prog_ac_ct_AR="$ac_ct_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_ac_ct_AR="ar"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
-  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
-echo "${ECHO_T}$ac_ct_AR" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  AR=$ac_ct_AR
-else
-  AR="$ac_cv_prog_AR"
-fi
-
-    STLIB_LD='${AR} cr'
-    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
-    if test "x$SHLIB_VERSION" = x; then
-  SHLIB_VERSION=""
-else
-  SHLIB_VERSION=".$SHLIB_VERSION"
-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 "$GCC" != "yes" -a ! -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
-               if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
-set dummy ${ac_tool_prefix}windres; 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_RC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$RC"; then
-  ac_cv_prog_RC="$RC" # 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_RC="${ac_tool_prefix}windres"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-RC=$ac_cv_prog_RC
-if test -n "$RC"; then
-  echo "$as_me:$LINENO: result: $RC" >&5
-echo "${ECHO_T}$RC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_RC"; then
-  ac_ct_RC=$RC
-  # Extract the first word of "windres", so it can be a program name with args.
-set dummy windres; 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_RC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_RC"; then
-  ac_cv_prog_ac_ct_RC="$ac_ct_RC" # 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_RC="windres"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_RC=$ac_cv_prog_ac_ct_RC
-if test -n "$ac_ct_RC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_RC" >&5
-echo "${ECHO_T}$ac_ct_RC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  RC=$ac_ct_RC
-else
-  RC="$ac_cv_prog_RC"
-fi
-
-               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}"
-
-               echo "$as_me:$LINENO: checking for cross-compile version of gcc" >&5
-echo $ECHO_N "checking for cross-compile version of gcc... $ECHO_C" >&6
-if test "${ac_cv_cross+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 _WIN32
-                               #error cross-compiler
-                           #endif
-
-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_cross=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_cross=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_cross" >&5
-echo "${ECHO_T}$ac_cv_cross" >&6
-                     if test "$ac_cv_cross" = "yes"; then
-                       case "$do64bit" in
-                           amd64|x64|yes)
-                               CC="x86_64-w64-mingw32-gcc"
-                               LD="x86_64-w64-mingw32-ld"
-                               AR="x86_64-w64-mingw32-ar"
-                               RANLIB="x86_64-w64-mingw32-ranlib"
-                               RC="x86_64-w64-mingw32-windres"
-                           ;;
-                           *)
-                               CC="i686-w64-mingw32-gcc"
-                               LD="i686-w64-mingw32-ld"
-                               AR="i686-w64-mingw32-ar"
-                               RANLIB="i686-w64-mingw32-ranlib"
-                               RC="i686-w64-mingw32-windres"
-                           ;;
-                       esac
-               fi
-
-           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_SUFFIX=".dll"
-           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
-
-           TCL_LIB_VERSIONS_OK=nodots
-           ;;
-       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_SUFFIX=".so"
-
-           LD_LIBRARY_PATH_VAR="LIBPATH"
-
-           # 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 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"
-               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 -Wl,-bexpall'
-
-else
-
-                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
-                   LDFLAGS="$LDFLAGS -brtl"
-
-fi
-
-               SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
-               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
-               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
-
-fi
-
-           ;;
-       BeOS*)
-           SHLIB_CFLAGS="-fPIC"
-           SHLIB_LD='${CC} -nostart'
-           SHLIB_SUFFIX=".so"
-
-           #-----------------------------------------------------------
-           # 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-4.*)
-           SHLIB_CFLAGS="-export-dynamic -fPIC"
-           SHLIB_LD='${CC} -shared'
-           SHLIB_SUFFIX=".so"
-           LDFLAGS="$LDFLAGS -export-dynamic"
-           CC_SEARCH_FLAGS=""
-           LD_SEARCH_FLAGS=""
-           ;;
-       CYGWIN_*)
-           SHLIB_CFLAGS=""
-           SHLIB_LD='${CC} -shared'
-           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a"
-           SHLIB_SUFFIX=".dll"
-           EXEEXT=".exe"
-           do64bit_ok=yes
-           CC_SEARCH_FLAGS=""
-           LD_SEARCH_FLAGS=""
-           ;;
-       Haiku*)
-           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
-           SHLIB_CFLAGS="-fPIC"
-           SHLIB_SUFFIX=".so"
-           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
-           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 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_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 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_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 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
-
-               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'
-               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'
-                           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
- ;;
-       IRIX-6.*)
-           SHLIB_CFLAGS=""
-           SHLIB_LD="ld -n32 -shared -rdata_shared"
-           SHLIB_SUFFIX=".so"
-           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_SUFFIX=".so"
-           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*|GNU*|NetBSD-Debian)
-           SHLIB_CFLAGS="-fPIC"
-           SHLIB_SUFFIX=".so"
-
-           # TEA specific:
-           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
-
-           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
-           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
-           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
-
-           ;;
-       Lynx*)
-           SHLIB_CFLAGS="-fPIC"
-           SHLIB_SUFFIX=".so"
-           CFLAGS_OPTIMIZE=-02
-           SHLIB_LD='${CC} -shared'
-           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
-
-           ;;
-       OpenBSD-*)
-           arch=`arch -s`
-           case "$arch" in
-           vax)
-               SHLIB_SUFFIX=""
-               SHARED_LIB_SUFFIX=""
-               LDFLAGS=""
-               ;;
-           *)
-               case "$arch" in
-               alpha|sparc64)
-                   SHLIB_CFLAGS="-fPIC"
-                   ;;
-               *)
-                   SHLIB_CFLAGS="-fpic"
-                   ;;
-               esac
-               SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
-               SHLIB_SUFFIX=".so"
-               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}'
-               LDFLAGS="-Wl,-export-dynamic"
-               ;;
-           esac
-           case "$arch" in
-           vax)
-               CFLAGS_OPTIMIZE="-O1"
-               ;;
-           *)
-               CFLAGS_OPTIMIZE="-O2"
-               ;;
-           esac
-           if test "${TCL_THREADS}" = "1"; then
-
-               # On OpenBSD:   Compile with -pthread
-               #               Don't link with -lpthread
-               LIBS=`echo $LIBS | sed s/-lpthread//`
-               CFLAGS="$CFLAGS -pthread"
-
-fi
-
-           # OpenBSD doesn't do version numbers with dots.
-           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
-           TCL_LIB_VERSIONS_OK=nodots
-           ;;
-       NetBSD-*)
-           # NetBSD has ELF and can use 'cc -shared' to build shared libs
-           SHLIB_CFLAGS="-fPIC"
-           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
-           SHLIB_SUFFIX=".so"
-           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
-
-           ;;
-       FreeBSD-*)
-           # This configuration from FreeBSD Ports.
-           SHLIB_CFLAGS="-fPIC"
-           SHLIB_LD="${CC} -shared"
-           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@"
-           SHLIB_SUFFIX=".so"
-           LDFLAGS=""
-           if test $doRpath = yes; then
-
-               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
-               LD_SEARCH_FLAGS='-Wl,-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
-
-           case $system in
-           FreeBSD-3.*)
-               # Version numbers are dot-stripped by system policy.
-               TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
-               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
-               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
-               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 compatibility 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_SUFFIX=".dylib"
-           # 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
-
-               tcl_cv_cc_visibility_hidden=yes
-
-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
-
-               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 { (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_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 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_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
-
-           ;;
-       OS/390-*)
-           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
-
-cat >>confdefs.h <<\_ACEOF
-#define _OE_SOCKETS 1
-_ACEOF
-
-           ;;
-       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_SUFFIX=".so"
-           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"
-           CC_SEARCH_FLAGS=""
-           LD_SEARCH_FLAGS=""
-           ;;
-       SCO_SV-3.2*)
-           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"
-           CC_SEARCH_FLAGS=""
-           LD_SEARCH_FLAGS=""
-           ;;
-       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"
-           SHLIB_SUFFIX=".so"
-           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
-
-
-           SHLIB_SUFFIX=".so"
-           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"
-           # 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
-
-
-
-
-    # Add in the arch flags late to ensure it wasn't removed.
-    # Not necessary in TEA, but this is aligned with core
-    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 "$GCC" = yes; then
-
-       case $system in
-           AIX-*) ;;
-           BSD/OS*) ;;
-           CYGWIN_*|MINGW32_*) ;;
-           IRIX*) ;;
-           NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
-           Darwin-*) ;;
-           SCO_SV-3.2*) ;;
-           windows) ;;
-           *) SHLIB_CFLAGS="-fPIC" ;;
-       esac
-fi
-
-
-    if test "$tcl_cv_cc_visibility_hidden" != yes; then
-
-
-cat >>confdefs.h <<\_ACEOF
-#define MODULE_SCOPE extern
-_ACEOF
-
-
-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
-
-
-    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
-       echo "$as_me:$LINENO: checking for SEH support in compiler" >&5
-echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6
-if test "${tcl_cv_seh+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  tcl_cv_seh=no
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-           int main(int argc, char** argv) {
-               int a, b = 0;
-               __try {
-                   a = 666 / b;
-               }
-               __except (EXCEPTION_EXECUTE_HANDLER) {
-                   return 0;
-               }
-               return 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
-  tcl_cv_seh=yes
-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 )
-tcl_cv_seh=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5
-echo "${ECHO_T}$tcl_cv_seh" >&6
-       if test "$tcl_cv_seh" = "no" ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NO_SEH 1
-_ACEOF
-
-       fi
-
-       #
-       # Check to see if the excpt.h include file provided contains the
-       # definition for EXCEPTION_DISPOSITION; if not, which is the case
-       # with Cygwin's version as of 2002-04-10, define it to be int,
-       # sufficient for getting the current code to work.
-       #
-       echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5
-echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6
-if test "${tcl_cv_eh_disposition+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 WIN32_LEAN_AND_MEAN
-#          include <windows.h>
-#          undef WIN32_LEAN_AND_MEAN
-
-int
-main ()
-{
-
-               EXCEPTION_DISPOSITION x;
-
-  ;
-  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_eh_disposition=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_eh_disposition=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5
-echo "${ECHO_T}$tcl_cv_eh_disposition" >&6
-       if test "$tcl_cv_eh_disposition" = "no" ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define EXCEPTION_DISPOSITION int
-_ACEOF
-
-       fi
-
-       # Check to see if winnt.h defines CHAR, SHORT, and LONG
-       # even if VOID has already been #defined. The win32api
-       # used by mingw and cygwin is known to do this.
-
-       echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5
-echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6
-if test "${tcl_cv_winnt_ignore_void+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 VOID void
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-int
-main ()
-{
-
-               CHAR c;
-               SHORT s;
-               LONG l;
-
-  ;
-  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_winnt_ignore_void=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_winnt_ignore_void=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5
-echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6
-       if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_WINNT_IGNORE_VOID 1
-_ACEOF
-
-       fi
-    fi
-
-       # See if the compiler supports casting to a union type.
-       # This is used to stop gcc from printing a compiler
-       # warning when initializing a union member.
-
-       echo "$as_me:$LINENO: checking for cast to union support" >&5
-echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6
-if test "${tcl_cv_cast_to_union+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 ()
-{
-
-                 union foo { int i; double d; };
-                 union foo f = (union foo) (int) 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_cv_cast_to_union=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cast_to_union=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5
-echo "${ECHO_T}$tcl_cv_cast_to_union" >&6
-       if test "$tcl_cv_cast_to_union" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CAST_TO_UNION 1
-_ACEOF
-
-       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 <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} -DNDEBUG"
-       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
-
-
-#--------------------------------------------------------------------
-# Enable compile-time support for TIP #143 and TIP #285.  When using
-# a pre-Tcl 8.5 or 8.6 core, respectively, the actual functionality
-# will not be available at runtime.
-#--------------------------------------------------------------------
-
-
-cat >>confdefs.h <<\_ACEOF
-#define TCL_TIP143 1
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define TCL_TIP285 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)"
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-print("manifest needed")
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "manifest needed" >/dev/null 2>&1; then
-
-       # Could do a CHECK_PROG for mt, but should always be with MSVC8+
-       VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;2 ; fi"
-       VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;1 ; fi"
-       MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
-
-    CLEANFILES="$CLEANFILES *.manifest"
-
-
-fi
-rm -f conftest*
-
-       MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -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.
-           if test x"${TK_BIN_DIR}" != x ; then
-               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
-           fi
-           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
-           if test "$GCC" = "yes"; then
-               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
-           fi
-           eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
-       else
-           eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
-           if test "$GCC" = "yes"; then
-               PKG_LIB_FILE=lib${PKG_LIB_FILE}
-           fi
-       fi
-       # Some packages build their own stubs libraries
-       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${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_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
-           RANLIB=:
-       else
-           eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
-       fi
-       # Some packages build their own stubs libraries
-       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${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
-
-
-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 thread $as_me 2.7.3, 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="\\
-thread config.status 2.7.3
-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
-_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_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;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,@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,@CLEANFILES@,$CLEANFILES,;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,@CPP@,$CPP,;t t
-s,@INSTALL@,$INSTALL,;t t
-s,@INSTALL_DATA_DIR@,$INSTALL_DATA_DIR,;t t
-s,@INSTALL_DATA@,$INSTALL_DATA,;t t
-s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
-s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
-s,@INSTALL_LIBRARY@,$INSTALL_LIBRARY,;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_THREADS@,$TCL_THREADS,;t t
-s,@SHARED_BUILD@,$SHARED_BUILD,;t t
-s,@AR@,$AR,;t t
-s,@ac_ct_AR@,$ac_ct_AR,;t t
-s,@CELIB_DIR@,$CELIB_DIR,;t t
-s,@RC@,$RC,;t t
-s,@ac_ct_RC@,$ac_ct_RC,;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,@VC_MANIFEST_EMBED_DLL@,$VC_MANIFEST_EMBED_DLL,;t t
-s,@VC_MANIFEST_EMBED_EXE@,$VC_MANIFEST_EMBED_EXE,;t t
-s,@TCLSH_PROG@,$TCLSH_PROG,;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
-
-
-
-  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
-" $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/pkgs/thread2.7.3/doc/html/thread.html b/pkgs/thread2.7.3/doc/html/thread.html
deleted file mode 100644 (file)
index 2ad1398..0000000
+++ /dev/null
@@ -1,727 +0,0 @@
-<! -- -*- tcl -*- doctools manpage
-   -->
-<html><head>
-<title>thread - Tcl Threading </title>
-</head>
-<! -- Generated from file '' by tcllib/doctools with format 'html'
-   -->
-
-<body>
-<h1> thread(n) 2.7  &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.7?</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/pkgs/thread2.7.3/doc/html/tpool.html b/pkgs/thread2.7.3/doc/html/tpool.html
deleted file mode 100644 (file)
index b59f0ee..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-<! -- -*- tcl -*- doctools manpage
-   -->
-<html><head>
-<title>tpool - Tcl Threading </title>
-</head>
-<! -- Generated from file '' by tcllib/doctools with format 'html'
-   -->
-
-<body>
-<h1> tpool(n) 2.7  &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.7?</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.
-
-<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/pkgs/thread2.7.3/doc/html/tsv.html b/pkgs/thread2.7.3/doc/html/tsv.html
deleted file mode 100644 (file)
index 40bbb96..0000000
+++ /dev/null
@@ -1,471 +0,0 @@
-<! -- -*- tcl -*- doctools manpage
-   -->
-<html><head>
-<title>tsv - Tcl Threading </title>
-</head>
-<! -- Generated from file '' by tcllib/doctools with format 'html'
-   -->
-
-<body>
-<h1> tsv(n) 2.7  &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.7?</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/pkgs/thread2.7.3/doc/html/ttrace.html b/pkgs/thread2.7.3/doc/html/ttrace.html
deleted file mode 100644 (file)
index 0b9d07b..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-<! -- -*- tcl -*- doctools manpage
-   -->
-<html><head>
-<title>ttrace - Tcl Threading </title>
-</head>
-<! -- Generated from file '' by tcllib/doctools with format 'html'
-   -->
-
-<body>
-<h1> ttrace(n) 2.7  &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.7?</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.7.0
-
-    % 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/pkgs/thread2.7.3/doc/man/tpool.n b/pkgs/thread2.7.3/doc/man/tpool.n
deleted file mode 100644 (file)
index 221319b..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-'\"
-'\" 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.
-'\"
-'\"    # 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.7  "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.7?\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.
-.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/pkgs/thread2.7.3/tests/tsv.test b/pkgs/thread2.7.3/tests/tsv.test
deleted file mode 100644 (file)
index a09c863..0000000
+++ /dev/null
@@ -1 +0,0 @@
-return
similarity index 96%
rename from pkgs/thread2.7.3/ChangeLog
rename to pkgs/thread2.8.0/ChangeLog
index d0fa6e8..79452cc 100644 (file)
@@ -1,3 +1,73 @@
+2016-06-03  Pietro Cerutti <gahr@gahr.ch>
+
+       * doc/*: Bump version to 2.8 in docs [Tkt b35544d2c8]
+
+2016-06-03  Pietro Cerutti <gahr@gahr.ch>
+
+       * generic/threadCmd.c: Add parenthesis to bit-shift macros [Tkt 957dbe231c]
+
+2016-05-31  Pietro Cerutti <gahr@gahr.ch>
+
+       * generic/threadSvCmd.c: Implement [tsv::handlers] command [Tkt 72b8ee4c76]
+       * doc/html/tsv.html
+       * doc/man/tsv.n
+       * doc/tsv.man
+       * tests/tsv.test
+
+2016-05-31  Pietro Cerutti <gahr@gahr.ch>
+
+       * generic/threadCmd.c: Add status arg to [thread::exit] [Tkt 3407860fff]
+       * tests/thread.test
+       * doc/thread.man
+       * doc/man/thread.n
+       * doc/html/thread.html
+
+2016-05-18  Pietro Cerutti <gahr@gahr.ch>
+
+       * generic/threadSvCmd.c: Fix race condition in thread finalization routine
+       [Tkt 3532972fff]
+       * tests/tkt-84be1b5a73.test: Add a test for [Tkt 84be1b5a73]
+
+2016-05-17  Pietro Cerutti <gahr@gahr.ch>
+
+       * generic/threadCmd.c: Fix -async and result trace [Tkt 84be1b5a73]
+       * doc/thread.man: Remove "id" arg from [thread::broadcast]'s manpage
+       * doc/man/thread.n: Regenerate documentation
+       * doc/html/thread.html
+
+2016-05-13  Pietro Cerutti <gahr@gahr.ch>
+
+       * aclocal.m4: Add support for LMDB persistent storage [Tkt 9378bb6795]
+       * configure
+       * configure.ac
+       * doc/html/tsv.html
+       * doc/man/tsv.n
+       * doc/tsv.man
+       * generic/psGdbm.c
+       * generic/psLmdb.c
+       * generic/psLmdb.h
+       * generic/threadSvCmd.c
+       * generic/threadSvCmd.h
+       * tests/French.txt version
+       * tests/store-load.tcl
+       * tests/tsv.test
+
+       * generic/tclThreadInt.h: Use spaces for indentation everywhere
+       * generic/tclXkeylist.c
+       * generic/threadCmd.c
+       * generic/threadNs.c
+       * generic/threadSpCmd.c
+       * generic/threadSpCmd.h
+       * generic/threadSvCmd.c
+
+2016-04-20  Pietro Cerutti <gahr@gahr.ch>
+
+       * configure, aclocal.m4: Correctly handle --without-gdbm [Tkt f8ff429a39]
+       * doc/tsv.man: Document side-effect of [tsv::array unbind] [Tkt be135da5f9]
+       * doc/*.(html|n): Regenerate documentation [Tkt 41922d3bb7]
+       * generic/threadSvCmd.c: Avoid double query to persistent storage in
+       tsv::array bind [Tkt a135697d8c]
+
 2013-05-23  Jan Nijtmans  <nijtmans@users.sf.net>
 
        * generic/threadSvKeylistCmd.c: Change a few internal variable
similarity index 89%
rename from pkgs/thread2.7.3/README
rename to pkgs/thread2.8.0/README
index 6c60093..7ec98db 100644 (file)
@@ -2,19 +2,19 @@
 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 
+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. 
+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. 
+support.
 
-This extension is a freely available open source package. You can do 
+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.
@@ -24,7 +24,7 @@ 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 
+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.
 
@@ -33,7 +33,7 @@ WHERE IS THE DOCUMENTATION ?
 ============================
 
 Documentation in Unix man and standard HTML format is available in the
-doc/man and doc/html directories respectively. 
+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
similarity index 50%
rename from pkgs/thread2.7.3/aclocal.m4
rename to pkgs/thread2.8.0/aclocal.m4
index 6744284..9a825fb 100644 (file)
@@ -22,7 +22,7 @@ AC_DEFUN(TCLTHREAD_WITH_GDBM, [
        [  --with-gdbm             link with optional GDBM support],\
        with_gdbm=${withval})
 
-    if test x"${with_gdbm}" != x; then
+    if test x"${with_gdbm}" != x -a "${with_gdbm}" != no; then
 
     AC_MSG_CHECKING([for GNU gdbm library])
 
@@ -70,4 +70,66 @@ AC_DEFUN(TCLTHREAD_WITH_GDBM, [
     fi
 ])
 
+
+#
+# Handle the "--with-lmdb" option for linking-in
+# the LMDB-based peristent store for shared arrays.
+# It tries to locate LMDB 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 LMDB lib files and
+# include files located in the same directory.
+#
+
+AC_DEFUN(TCLTHREAD_WITH_LMDB, [
+    AC_ARG_WITH(lmdb,
+       [  --with-lmdb             link with optional LMDB support],
+       with_lmdb=${withval})
+
+    if test x"${with_lmdb}" != "x" -a "${with_lmdb}" != no; then
+        AC_MSG_CHECKING([for LMDB library])
+        AC_CACHE_VAL(ac_cv_c_lmdb,[
+        if test x"${with_lmdb}" != x -a "${with_lmdb}" != "yes"; then
+            if test -f "${with_lmdb}/lmdb.h" -a x"`ls ${with_lmdb}/liblmdb* 2>/dev/null`" != x; then
+                ac_cv_c_lmdb=`(cd ${with_lmdb}; pwd)`
+                lincdir=$ac_cv_c_lmdb
+                llibdir=$ac_cv_c_lmdb
+                AC_MSG_RESULT([found in $llibdir])
+            else
+                AC_MSG_ERROR([${with_lmdb} directory doesn't contain lmdb library])
+            fi
+        fi
+        ])
+        if test x"${lincdir}" = x -o x"${llibdir}" = 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/liblmdb* 2>/dev/null`" != x ; then
+                    llibdir=`(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/lmdb.h" ; then
+                    lincdir=`(cd $i; pwd)`
+                    break
+                fi
+            done
+            if test x"$llibdir" = x -o x"$lincdir" = x ; then
+                AC_MSG_ERROR([none found])
+            else
+                AC_MSG_RESULT([found in $llibdir, includes in $lincdir])
+                AC_DEFINE(HAVE_LMDB)
+                LMDB_CFLAGS="-I\"$lincdir\""
+                LMDB_LIBS="-L\"$llibdir\" -llmdb"
+            fi
+        fi
+    fi
+])
+
 # EOF
diff --git a/pkgs/thread2.8.0/configure b/pkgs/thread2.8.0/configure
new file mode 100755 (executable)
index 0000000..2aa66a8
--- /dev/null
@@ -0,0 +1,10164 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for thread 2.8.0.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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=:
+  # Pre-4.2 versions of Zsh do 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_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+       expr "X$arg" : "X\\(.*\\)$as_nl";
+       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+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.)
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+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
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do 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_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+        /*)
+          for as_base in sh bash ksh sh5; do
+            # Try only shells that exist, to save several forks.
+            as_shell=$as_dir/$as_base
+            if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+                   { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+                  if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+          done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+             { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_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 ||
+$as_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" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+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
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# 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
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # 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" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='        ';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+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 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/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=
+
+# Identity of this package.
+PACKAGE_NAME='thread'
+PACKAGE_TARNAME='thread'
+PACKAGE_VERSION='2.8.0'
+PACKAGE_STRING='thread 2.8.0'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+# 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='LTLIBOBJS
+LIBOBJS
+TCLSH_PROG
+VC_MANIFEST_EMBED_EXE
+VC_MANIFEST_EMBED_DLL
+RANLIB_STUB
+MAKE_STUB_LIB
+MAKE_STATIC_LIB
+MAKE_SHARED_LIB
+MAKE_LIB
+TCL_DBGX
+LDFLAGS_DEFAULT
+CFLAGS_DEFAULT
+LD_LIBRARY_PATH_VAR
+SHLIB_CFLAGS
+SHLIB_LD_LIBS
+SHLIB_LD
+STLIB_LD
+CFLAGS_WARNING
+CFLAGS_OPTIMIZE
+CFLAGS_DEBUG
+RC
+CELIB_DIR
+AR
+STUBS_BUILD
+SHARED_BUILD
+TCL_THREADS
+TCL_INCLUDES
+PKG_OBJECTS
+PKG_SOURCES
+MATH_LIBS
+EGREP
+GREP
+RANLIB
+SET_MAKE
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
+CPP
+TCL_SHLIB_LD_LIBS
+TCL_LD_FLAGS
+TCL_EXTRA_CFLAGS
+TCL_DEFS
+TCL_LIBS
+CLEANFILES
+OBJEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+TCL_STUB_LIB_SPEC
+TCL_STUB_LIB_FLAG
+TCL_STUB_LIB_FILE
+TCL_LIB_SPEC
+TCL_LIB_FLAG
+TCL_LIB_FILE
+TCL_SRC_DIR
+TCL_BIN_DIR
+TCL_PATCH_LEVEL
+TCL_VERSION
+PKG_CFLAGS
+PKG_LIBS
+PKG_INCLUDES
+PKG_HEADERS
+PKG_TCL_SOURCES
+PKG_STUB_OBJECTS
+PKG_STUB_SOURCES
+PKG_STUB_LIB_FILE
+PKG_LIB_FILE
+EXEEXT
+CYGPATH
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_tcl
+with_gdbm
+with_lmdb
+with_naviserver
+with_tclinclude
+enable_threads
+enable_shared
+enable_stubs
+enable_64bit
+enable_64bit_vis
+enable_rpath
+enable_wince
+with_celib
+enable_symbols
+'
+      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
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# 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= ;;
+  *)    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_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=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_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=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 ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_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'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+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
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+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
+  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 .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# 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 -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_myself" : 'X\(//\)[^/]' \| \
+        X"$as_myself" : 'X\(//\)$' \| \
+        X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    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 .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+       cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+       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.8.0 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.8.0:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --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-stubs          build and link with stub libraries. Always true for
+                          shared builds (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-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-lmdb             link with optional LMDB support
+  --with-naviserver       directory with NaviServer/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    (Objective) 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.
+
+Report bugs to the package provider.
+_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" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && 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=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_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
+      $as_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.8.0
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); 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 $2
+
+/* 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 $2 ();
+/* 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_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+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.8.0, which was
+generated by GNU Autoconf 2.69.  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=.
+    $as_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=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append 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
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset 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
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; 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
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=\$$ac_var
+       case $ac_val in
+       *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+       esac
+       $as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_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'; as_fn_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
+
+$as_echo "/* confdefs.h */" > 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
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_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,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_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
+       # differences in whitespace do not lead to failure.
+       ac_old_val_w=`echo x $ac_old_val`
+       ac_new_val_w=`echo x $ac_new_val`
+       if test "$ac_old_val_w" != "$ac_new_val_w"; then
+         { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+         ac_cache_corrupted=:
+       else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+         eval $ac_var=\$ac_old_val
+       fi
+       { $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_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.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+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.10"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
+$as_echo_n "checking for correct TEA configuration... " >&6; }
+    if test x"${PACKAGE_NAME}" = x ; then
+       as_fn_error $? "
+The PACKAGE_NAME variable must be defined by your TEA configure.ac" "$LINENO" 5
+    fi
+    if test x"3.9" = x ; then
+       as_fn_error $? "
+TEA version not specified." "$LINENO" 5
+    elif test "3.9" != "${TEA_VERSION}" ; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&5
+$as_echo "warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&6; }
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (TEA ${TEA_VERSION})" >&5
+$as_echo "ok (TEA ${TEA_VERSION})" >&6; }
+    fi
+
+    # If the user did not set CFLAGS, set it now to keep macros
+    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CYGPATH+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CYGPATH="cygpath -m"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
+$as_echo "$CYGPATH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *CYGWIN_*)
+           EXEEXT=".exe"
+           # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG
+           ;;
+       *)
+           CYGPATH=echo
+           # Maybe we are cross-compiling....
+           case ${host_alias} in
+               *mingw32*)
+               EXEEXT=".exe"
+               TEA_PLATFORM="windows"
+               ;;
+           *)
+               EXEEXT=""
+               TEA_PLATFORM="unix"
+               ;;
+           esac
+           ;;
+    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
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&5
+$as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+
+
+
+
+    # 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
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in tclconfig \"$srcdir\"/tclconfig" "$LINENO" 5
+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
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
+$as_echo_n "checking for Tcl configuration... " >&6; }
+       if ${ac_cv_c_tclconfig+:} false; then :
+  $as_echo_n "(cached) " >&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
+                           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+$as_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
+                   as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
+               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` \
+                       `ls -d /usr/lib64 2>/dev/null` \
+                       `ls -d /usr/lib/tcl8.6 2>/dev/null` \
+                       `ls -d /usr/lib/tcl8.5 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"
+           as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
+       else
+           no_tcl=
+           TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
+       fi
+    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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_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"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM 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.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; 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 | *.dSYM | *.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
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; 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 | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; 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 | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+        CFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* 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"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+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)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+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
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
+$as_echo "loading" >&6; }
+       . "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo "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" | 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}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking platform" >&5
+$as_echo_n "checking platform... " >&6; }
+    hold_cc=$CC; CC="$TCL_CC"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+           #ifdef _WIN32
+               #error win32
+           #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+           TEA_PLATFORM="unix"
+           CYGPATH=echo
+
+else
+
+           TEA_PLATFORM="windows"
+           # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CYGPATH+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CYGPATH="cygpath -m"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
+$as_echo "$CYGPATH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    CC=$hold_cc
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEA_PLATFORM" >&5
+$as_echo "$TEA_PLATFORM" >&6; }
+
+    # The BUILD_$pkg is to define the correct extern storage class
+    # handling when making this package
+
+cat >>confdefs.h <<_ACEOF
+#define BUILD_${PACKAGE_NAME} /**/
+_ACEOF
+
+    # Do this here as we have fully defined TEA_PLATFORM now
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       EXEEXT=".exe"
+       CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
+    fi
+
+    # TEA specific:
+
+
+
+
+
+
+
+
+if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
+    as_fn_error $? "${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.4+
+Found config for Tcl ${TCL_VERSION}" "$LINENO" 5
+fi
+if test "${TCL_MINOR_VERSION}" -lt 4 ; then
+    as_fn_error $? "${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.4+
+Found config for Tcl ${TCL_VERSION}" "$LINENO" 5
+fi
+
+#--------------------------------------------------------------------
+# 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
+           { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+$as_echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+           prefix=${TCL_PREFIX}
+       else
+           { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to /usr/local" >&5
+$as_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
+           { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+$as_echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to ${prefix}" >&5
+$as_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 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.
+
+    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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_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"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+        CFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* 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"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+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)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+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_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+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
+
+
+    INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+    INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+    INSTALL_DATA='${INSTALL} -m 644'
+    INSTALL_PROGRAM='${INSTALL}'
+    INSTALL_SCRIPT='${INSTALL}'
+    INSTALL_LIBRARY='${INSTALL_DATA}'
+
+
+
+
+
+
+
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&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.)
+    #--------------------------------------------------------------------
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  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"
+      as_fn_executable_p "$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
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_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
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    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
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  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"
+      as_fn_executable_p "$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
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_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
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    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
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_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
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5
+$as_echo_n "checking if the compiler understands -pipe... " >&6; }
+if ${tcl_cv_cc_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_cc_pipe=yes
+else
+  tcl_cv_cc_pipe=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5
+$as_echo "$tcl_cv_cc_pipe" >&6; }
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+              not a universal capable compiler
+            #endif
+            typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+       # Check for potential -arch flags.  It is not universal unless
+       # there are at least two -arch flags with different values.
+       ac_arch=
+       ac_prev=
+       for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+        if test -n "$ac_prev"; then
+          case $ac_word in
+            i?86 | x86_64 | ppc | ppc64)
+              if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+                ac_arch=$ac_word
+              else
+                ac_cv_c_bigendian=universal
+                break
+              fi
+              ;;
+          esac
+          ac_prev=
+        elif test "x$ac_word" = "x-arch"; then
+          ac_prev=arch
+        fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=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 $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+             bogus endian macros
+            #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+                not big endian
+               #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=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 $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 };
+               int use_ascii (int i) {
+                 return ascii_mm[i] + ascii_ii[i];
+               }
+               short int ebcdic_ii[] =
+                 { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+               short int ebcdic_mm[] =
+                 { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+               int use_ebcdic (int i) {
+                 return ebcdic_mm[i] + ebcdic_ii[i];
+               }
+               extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; 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
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ 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").
+    #--------------------------------------------------------------------
+
+    ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin"
+if test "x$ac_cv_func_sin" = xyes; then :
+  MATH_LIBS=""
+else
+  MATH_LIBS="-lm"
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5
+$as_echo_n "checking for main in -lieee... " >&6; }
+if ${ac_cv_lib_ieee_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ieee_main=yes
+else
+  ac_cv_lib_ieee_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5
+$as_echo "$ac_cv_lib_ieee_main" >&6; }
+if test "x$ac_cv_lib_ieee_main" = xyes; 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.
+    #--------------------------------------------------------------------
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -linet" >&5
+$as_echo_n "checking for main in -linet... " >&6; }
+if ${ac_cv_lib_inet_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_inet_main=yes
+else
+  ac_cv_lib_inet_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_main" >&5
+$as_echo "$ac_cv_lib_inet_main" >&6; }
+if test "x$ac_cv_lib_inet_main" = xyes; then :
+  LIBS="$LIBS -linet"
+fi
+
+    ac_fn_c_check_header_mongrel "$LINENO" "net/errno.h" "ac_cv_header_net_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_net_errno_h" = xyes; then :
+
+
+$as_echo "#define HAVE_NET_ERRNO_H 1" >>confdefs.h
+
+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
+    ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
+if test "x$ac_cv_func_connect" = xyes; then :
+  tcl_checkSocket=0
+else
+  tcl_checkSocket=1
+fi
+
+    if test "$tcl_checkSocket" = 1; then
+       ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt"
+if test "x$ac_cv_func_setsockopt" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5
+$as_echo_n "checking for setsockopt in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_setsockopt+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_socket_setsockopt=yes
+else
+  ac_cv_lib_socket_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5
+$as_echo "$ac_cv_lib_socket_setsockopt" >&6; }
+if test "x$ac_cv_lib_socket_setsockopt" = xyes; then :
+  LIBS="$LIBS -lsocket"
+else
+  tcl_checkBoth=1
+fi
+
+fi
+
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       ac_fn_c_check_func "$LINENO" "accept" "ac_cv_func_accept"
+if test "x$ac_cv_func_accept" = xyes; then :
+  tcl_checkNsl=0
+else
+  LIBS=$tk_oldLibs
+fi
+
+    fi
+    ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; 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}'
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dirent.h" >&5
+$as_echo_n "checking dirent.h... " >&6; }
+if ${tcl_cv_dirent_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_dirent_h=yes
+else
+  tcl_cv_dirent_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_dirent_h" >&5
+$as_echo "$tcl_cv_dirent_h" >&6; }
+
+    if test $tcl_cv_dirent_h = no; then
+
+$as_echo "#define NO_DIRENT_H 1" >>confdefs.h
+
+    fi
+
+    # TEA specific:
+    ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_errno_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_ERRNO_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_FLOAT_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "values.h" "ac_cv_header_values_h" "$ac_includes_default"
+if test "x$ac_cv_header_values_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_VALUES_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes; then :
+
+$as_echo "#define HAVE_LIMITS_H 1" >>confdefs.h
+
+else
+
+$as_echo "#define NO_LIMITS_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+
+$as_echo "#define NO_STDLIB_H 1" >>confdefs.h
+
+    fi
+    ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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
+
+$as_echo "#define NO_STRING_H 1" >>confdefs.h
+
+    fi
+
+    ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_DLFCN_H 1" >>confdefs.h
+
+fi
+
+
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    for ac_header in sys/param.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_PARAM_H 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 -a "${with_gdbm}" != no; then
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gdbm library" >&5
+$as_echo_n "checking for GNU gdbm library... " >&6; }
+
+    if ${ac_cv_c_gdbm+:} false; then :
+  $as_echo_n "(cached) " >&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
+            { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $glibdir" >&5
+$as_echo "found in $glibdir" >&6; }
+        else
+            as_fn_error $? "${with_gdbm} directory doesn't contain gdbm library" "$LINENO" 5
+        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
+            as_fn_error $? "none found" "$LINENO" 5
+        else
+            { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $glibdir, includes in $gincdir" >&5
+$as_echo "found in $glibdir, includes in $gincdir" >&6; }
+            $as_echo "#define HAVE_GDBM 1" >>confdefs.h
+
+            GDBM_CFLAGS="-I\"$gincdir\""
+            GDBM_LIBS="-L\"$glibdir\" -lgdbm"
+        fi
+    fi
+    fi
+
+
+#--------------------------------------------------------------------
+# Check if building with optional lmdb package. This will declare
+# LMDB_CFLAGS and LMDB_LIBS variables.
+#--------------------------------------------------------------------
+
+
+
+# Check whether --with-lmdb was given.
+if test "${with_lmdb+set}" = set; then :
+  withval=$with_lmdb; with_lmdb=${withval}
+fi
+
+
+    if test x"${with_lmdb}" != "x" -a "${with_lmdb}" != no; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LMDB library" >&5
+$as_echo_n "checking for LMDB library... " >&6; }
+        if ${ac_cv_c_lmdb+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+        if test x"${with_lmdb}" != x -a "${with_lmdb}" != "yes"; then
+            if test -f "${with_lmdb}/lmdb.h" -a x"`ls ${with_lmdb}/liblmdb* 2>/dev/null`" != x; then
+                ac_cv_c_lmdb=`(cd ${with_lmdb}; pwd)`
+                lincdir=$ac_cv_c_lmdb
+                llibdir=$ac_cv_c_lmdb
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $llibdir" >&5
+$as_echo "found in $llibdir" >&6; }
+            else
+                as_fn_error $? "${with_lmdb} directory doesn't contain lmdb library" "$LINENO" 5
+            fi
+        fi
+
+fi
+
+        if test x"${lincdir}" = x -o x"${llibdir}" = 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/liblmdb* 2>/dev/null`" != x ; then
+                    llibdir=`(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/lmdb.h" ; then
+                    lincdir=`(cd $i; pwd)`
+                    break
+                fi
+            done
+            if test x"$llibdir" = x -o x"$lincdir" = x ; then
+                as_fn_error $? "none found" "$LINENO" 5
+            else
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $llibdir, includes in $lincdir" >&5
+$as_echo "found in $llibdir, includes in $lincdir" >&6; }
+                $as_echo "#define HAVE_LMDB 1" >>confdefs.h
+
+                LMDB_CFLAGS="-I\"$lincdir\""
+                LMDB_LIBS="-L\"$llibdir\" -llmdb"
+            fi
+        fi
+    fi
+
+
+#--------------------------------------------------------------------
+# Locate the NaviServer/AOLserver dir for compilation as NaviServer/AOLserver module.
+# This will declare NS_INCLUDES, NS_LIBS and define NS_AOLSERVER.
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NaviServer/AOLserver configuration" >&5
+$as_echo_n "checking for NaviServer/AOLserver configuration... " >&6; }
+
+# Check whether --with-naviserver was given.
+if test "${with_naviserver+set}" = set; then :
+  withval=$with_naviserver; \
+    with_naviserver=${withval}
+fi
+
+
+    if ${ac_cv_c_naviserver+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    if test x"${with_naviserver}" != x ; then
+        if test -f "${with_naviserver}/include/ns.h" ; then
+            ac_cv_c_naviserver=`(cd ${with_naviserver}; pwd)`
+        else
+            as_fn_error $? "${with_naviserver} directory doesn't contain ns.h" "$LINENO" 5
+        fi
+    fi
+
+fi
+
+    if test x"${ac_cv_c_naviserver}" = x ; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: none found" >&5
+$as_echo "none found" >&6; }
+    else
+        NS_DIR=${ac_cv_c_naviserver}
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: found NaviServer/AOLserver in $NS_DIR" >&5
+$as_echo "found NaviServer/AOLserver in $NS_DIR" >&6; }
+        NS_INCLUDES="-I\"${NS_DIR}/include\""
+        if test "`uname -s`" = Darwin ; then
+            aollibs=`ls ${NS_DIR}/lib/libns* 2>/dev/null`
+            if test x"$aollibs" != x ; then
+                NS_LIBS="-L\"${NS_DIR}/lib\" -lnsd -lnsthread"
+            fi
+        fi
+        $as_echo "#define NS_AOLSERVER 1" >>confdefs.h
+
+    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/threadNs.c           \
+                 generic/threadCmd.c          \
+                 generic/threadSvCmd.c        \
+                 generic/threadSpCmd.c        \
+                 generic/threadPoolCmd.c      \
+                 generic/psGdbm.c             \
+                 generic/psLmdb.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" \
+                   -a ! -f "${srcdir}/macosx/$i" \
+                   ; then
+                   as_fn_error $? "could not find source file '$i'" "$LINENO" 5
+               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/tclThread.h"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           as_fn_error $? "could not find header file '${srcdir}/$i'" "$LINENO" 5
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+
+
+
+    vars="${NS_INCLUDES}"
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+
+    vars="${GDBM_LIBS} ${LMDB_LIBS} ${NS_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} ${LMDB_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" \
+           -a ! -f "${srcdir}/macosx/$i" \
+           ; then
+           as_fn_error $? "could not find stub source file '$i'" "$LINENO" 5
+       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
+           as_fn_error $? "could not find tcl source file '${srcdir}/$i'" "$LINENO" 5
+       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
+
+    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" \
+                   -a ! -f "${srcdir}/macosx/$i" \
+                   ; then
+                   as_fn_error $? "could not find source file '$i'" "$LINENO" 5
+               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" \
+                   -a ! -f "${srcdir}/macosx/$i" \
+                   ; then
+                   as_fn_error $? "could not find source file '$i'" "$LINENO" 5
+               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
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl public headers" >&5
+$as_echo_n "checking for Tcl public headers... " >&6; }
+
+
+# Check whether --with-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then :
+  withval=$with_tclinclude; with_tclinclude=${withval}
+fi
+
+
+    if ${ac_cv_c_tclh+:} false; then :
+  $as_echo_n "(cached) " >&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
+               as_fn_error $? "${with_tclinclude} directory does not contain tcl.h" "$LINENO" 5
+           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
+       as_fn_error $? "tcl.h not found.  Please specify its location with --with-tclinclude" "$LINENO" 5
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tclh}" >&5
+$as_echo "${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
+
+$as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+           if test "`uname -s`" = "SunOS" ; then
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+           fi
+
+$as_echo "#define _THREAD_SAFE 1" >>confdefs.h
+
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; 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]
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for __pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread___pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __pthread_mutex_init ();
+int
+main ()
+{
+return __pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthread___pthread_mutex_init=yes
+else
+  ac_cv_lib_pthread___pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread___pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread___pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthreads" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthreads... " >&6; }
+if ${ac_cv_lib_pthreads_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthreads_pthread_mutex_init=yes
+else
+  ac_cv_lib_pthreads_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc... " >&6; }
+if ${ac_cv_lib_c_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_c_pthread_mutex_init=yes
+else
+  ac_cv_lib_c_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                   if test "$tcl_ok" = "no"; then
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc_r" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc_r... " >&6; }
+if ${ac_cv_lib_c_r_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_c_r_pthread_mutex_init=yes
+else
+  ac_cv_lib_c_r_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_r_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_r_pthread_mutex_init" = xyes; 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
+                           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
+$as_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
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5
+$as_echo_n "checking for building with threads... " >&6; }
+    if test "${TCL_THREADS}" = 1; then
+
+$as_echo "#define TCL_THREADS 1" >>confdefs.h
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (default)" >&5
+$as_echo "yes (default)" >&6; }
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+               { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&5
+$as_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
+               { $as_echo "$as_me:${as_lineno-$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
+$as_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.
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
+$as_echo_n "checking how to build libraries... " >&6; }
+    # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; shared_ok=$enableval
+else
+  shared_ok=yes
+fi
+
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       shared_ok=$enableval
+    else
+       shared_ok=yes
+    fi
+
+    # Check whether --enable-stubs was given.
+if test "${enable_stubs+set}" = set; then :
+  enableval=$enable_stubs; stubs_ok=$enableval
+else
+  stubs_ok=yes
+fi
+
+
+    if test "${enable_stubs+set}" = set; then
+       enableval="$enable_stubs"
+       stubs_ok=$enableval
+    else
+       stubs_ok=yes
+    fi
+
+    # Stubs are always enabled for shared builds
+    if test "$shared_ok" = "yes" ; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
+$as_echo "shared" >&6; }
+       SHARED_BUILD=1
+        STUBS_BUILD=1
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+       SHARED_BUILD=0
+
+$as_echo "#define STATIC_BUILD 1" >>confdefs.h
+
+        if test "$stubs_ok" = "yes" ; then
+          STUBS_BUILD=1
+        else
+          STUBS_BUILD=0
+        fi
+    fi
+    if test "${STUBS_BUILD}" = "1" ; then
+
+$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
+
+
+$as_echo "#define USE_TCLOO_STUBS 1" >>confdefs.h
+
+      if test "${TEA_WINDOWINGSYSTEM}" != ""; then
+
+$as_echo "#define USE_TK_STUBS 1" >>confdefs.h
+
+      fi
+    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.
+#--------------------------------------------------------------------
+
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+
+    # Step 0.a: Enable 64 bit support?
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
+$as_echo_n "checking if 64bit support is requested... " >&6; }
+    # Check whether --enable-64bit was given.
+if test "${enable_64bit+set}" = set; then :
+  enableval=$enable_64bit; do64bit=$enableval
+else
+  do64bit=no
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
+$as_echo "$do64bit" >&6; }
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5
+$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&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
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
+$as_echo "$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.
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5
+$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; }
+if ${tcl_cv_cc_visibility_hidden+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+       hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+           extern __attribute__((__visibility__("hidden"))) void f(void);
+           void f(void) {}
+int
+main ()
+{
+f();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_visibility_hidden=yes
+else
+  tcl_cv_cc_visibility_hidden=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+       CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5
+$as_echo "$tcl_cv_cc_visibility_hidden" >&6; }
+    if test $tcl_cv_cc_visibility_hidden = yes; then :
+
+
+$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h
+
+
+$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h
+
+
+fi
+
+    # Step 0.d: Disable -rpath support?
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5
+$as_echo_n "checking if rpath support is requested... " >&6; }
+    # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+  enableval=$enable_rpath; doRpath=$enableval
+else
+  doRpath=yes
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
+$as_echo "$doRpath" >&6; }
+
+    # TEA specific: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = windows; then :
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Windows/CE build is requested" >&5
+$as_echo_n "checking if Windows/CE build is requested... " >&6; }
+       # Check whether --enable-wince was given.
+if test "${enable_wince+set}" = set; then :
+  enableval=$enable_wince; doWince=$enableval
+else
+  doWince=no
+fi
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doWince" >&5
+$as_echo "$doWince" >&6; }
+
+fi
+
+    # Set the variable "system" to hold the name and version number
+    # for the system.
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5
+$as_echo_n "checking system version... " >&6; }
+if ${tcl_cv_sys_version+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+       # TEA specific:
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
+$as_echo "$as_me: WARNING: can't find uname command" >&2;}
+               tcl_cv_sys_version=unknown
+           else
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
+$as_echo "$tcl_cv_sys_version" >&6; }
+    system=$tcl_cv_sys_version
+
+
+    # Require ranlib early so we can override it in special cases below.
+
+
+
+    # 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 and removed some core-only vars.
+
+    do64bit_ok=no
+    # default to '{$LIBS}' and set to "" on per-platform necessary basis
+    SHLIB_LD_LIBS='${LIBS}'
+    # 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=""
+    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
+    if test "$GCC" = yes; then :
+
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall"
+
+else
+
+       CFLAGS_OPTIMIZE=-O
+       CFLAGS_WARNING=""
+
+fi
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    $as_echo "$as_me:${as_lineno-$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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AR" = x; then
+    AR=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    if test "x$SHLIB_VERSION" = x; then :
+  SHLIB_VERSION=""
+else
+  SHLIB_VERSION=".$SHLIB_VERSION"
+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 "$GCC" != "yes" -a ! -d "${PATH64}" ; then
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+$as_echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ensure latest Platform SDK is installed" >&5
+$as_echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+                   do64bit="no"
+               else
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
+$as_echo "   Using 64-bit $MACHINE mode" >&6; }
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   as_fn_error $? "Windows/CE and 64-bit builds incompatible" "$LINENO" 5
+               fi
+               if test "$GCC" = "yes" ; then
+                   as_fn_error $? "Windows/CE and GCC builds incompatible" "$LINENO" 5
+               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
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows/CE celib directory" >&5
+$as_echo_n "checking for Windows/CE celib directory... " >&6; }
+       if ${ac_cv_c_celibconfig+:} false; then :
+  $as_echo_n "(cached) " >&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
+                   as_fn_error $? "${with_celibconfig} directory doesn't contain inc directory" "$LINENO" 5
+               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
+           as_fn_error $? "Cannot find celib support library directory" "$LINENO" 5
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $CELIB_DIR" >&5
+$as_echo "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
+                   as_fn_error $? "could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" "$LINENO" 5
+                   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
+               case "x`echo \${VisualStudioVersion}`" in
+                   x1[4-9]*)
+                       lflags="${lflags} -nodefaultlib:libucrt.lib"
+
+    vars="ucrt.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
+
+
+                   ;;
+                   *)
+                   ;;
+               esac
+
+                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="${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="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+
+               else
+                   RC="rc"
+                   lflags="${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
+               if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
+set dummy ${ac_tool_prefix}windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RC"; then
+  ac_cv_prog_RC="$RC" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RC="${ac_tool_prefix}windres"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RC=$ac_cv_prog_RC
+if test -n "$RC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
+$as_echo "$RC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RC"; then
+  ac_ct_RC=$RC
+  # Extract the first word of "windres", so it can be a program name with args.
+set dummy windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RC"; then
+  ac_cv_prog_ac_ct_RC="$ac_ct_RC" # 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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RC="windres"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RC=$ac_cv_prog_ac_ct_RC
+if test -n "$ac_ct_RC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
+$as_echo "$ac_ct_RC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RC" = x; then
+    RC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RC=$ac_ct_RC
+  fi
+else
+  RC="$ac_cv_prog_RC"
+fi
+
+               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}"
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
+$as_echo_n "checking for cross-compile version of gcc... " >&6; }
+if ${ac_cv_cross+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+                           #ifdef _WIN32
+                               #error cross-compiler
+                           #endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_cross=yes
+else
+  ac_cv_cross=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
+$as_echo "$ac_cv_cross" >&6; }
+                     if test "$ac_cv_cross" = "yes"; then
+                       case "$do64bit" in
+                           amd64|x64|yes)
+                               CC="x86_64-w64-mingw32-gcc"
+                               LD="x86_64-w64-mingw32-ld"
+                               AR="x86_64-w64-mingw32-ar"
+                               RANLIB="x86_64-w64-mingw32-ranlib"
+                               RC="x86_64-w64-mingw32-windres"
+                           ;;
+                           *)
+                               CC="i686-w64-mingw32-gcc"
+                               LD="i686-w64-mingw32-ld"
+                               AR="i686-w64-mingw32-ar"
+                               RANLIB="i686-w64-mingw32-ranlib"
+                               RC="i686-w64-mingw32-windres"
+                           ;;
+                       esac
+               fi
+
+           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_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       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
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5
+$as_echo "Using $CC for compiling with threads" >&6; }
+
+fi
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_SUFFIX=".so"
+
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = yes; then :
+
+               if test "$GCC" = yes; then :
+
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_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"
+               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 -Wl,-bexpall'
+
+else
+
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+                   LDFLAGS="$LDFLAGS -brtl"
+
+fi
+               SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -nostart'
+           SHLIB_SUFFIX=".so"
+
+           #-----------------------------------------------------------
+           # 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.
+           #-----------------------------------------------------------
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5
+$as_echo_n "checking for inet_ntoa in -lbind... " >&6; }
+if ${ac_cv_lib_bind_inet_ntoa+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_bind_inet_ntoa=yes
+else
+  ac_cv_lib_bind_inet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then :
+  LIBS="$LIBS -lbind -lsocket"
+fi
+
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD='${CC} -shared'
+           SHLIB_SUFFIX=".so"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       CYGWIN_*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD='${CC} -shared'
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a"
+           SHLIB_SUFFIX=".dll"
+           EXEEXT=".exe"
+           do64bit_ok=yes
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       Haiku*)
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_SUFFIX=".so"
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5
+$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; }
+if ${ac_cv_lib_network_inet_ntoa+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetwork  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_network_inet_ntoa=yes
+else
+  ac_cv_lib_network_inet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then :
+  LIBS="$LIBS -lnetwork"
+fi
+
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+
+$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h
+
+           # 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
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then :
+
+               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'
+               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'
+                           if test $doRpath = yes; then :
+
+                               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_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 ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_SUFFIX=".so"
+           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_SUFFIX=".so"
+           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 :
+
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5
+$as_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*|GNU*|NetBSD-Debian)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_SUFFIX=".so"
+
+           # TEA specific:
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           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 :
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5
+$as_echo_n "checking if compiler accepts -m64 flag... " >&6; }
+if ${tcl_cv_cc_m64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_m64=yes
+else
+  tcl_cv_cc_m64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+                   CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5
+$as_echo "$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
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD='${CC} -shared'
+           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
+           ;;
+       OpenBSD-*)
+           arch=`arch -s`
+           case "$arch" in
+           vax)
+               SHLIB_SUFFIX=""
+               SHARED_LIB_SUFFIX=""
+               LDFLAGS=""
+               ;;
+           *)
+               case "$arch" in
+               alpha|sparc64)
+                   SHLIB_CFLAGS="-fPIC"
+                   ;;
+               *)
+                   SHLIB_CFLAGS="-fpic"
+                   ;;
+               esac
+               SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+               SHLIB_SUFFIX=".so"
+               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}'
+               LDFLAGS="-Wl,-export-dynamic"
+               ;;
+           esac
+           case "$arch" in
+           vax)
+               CFLAGS_OPTIMIZE="-O1"
+               ;;
+           *)
+               CFLAGS_OPTIMIZE="-O2"
+               ;;
+           esac
+           if test "${TCL_THREADS}" = "1"; then :
+
+               # On OpenBSD:   Compile with -pthread
+               #               Don't link with -lpthread
+               LIBS=`echo $LIBS | sed s/-lpthread//`
+               CFLAGS="$CFLAGS -pthread"
+
+fi
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       NetBSD-*)
+           # NetBSD has ELF and can use 'cc -shared' to build shared libs
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_SUFFIX=".so"
+           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
+           ;;
+       FreeBSD-*)
+           # This configuration from FreeBSD Ports.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -shared"
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@"
+           SHLIB_SUFFIX=".so"
+           LDFLAGS=""
+           if test $doRpath = yes; then :
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-Wl,-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
+           case $system in
+           FreeBSD-3.*)
+               # Version numbers are dot-stripped by system policy.
+               TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+               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)
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; }
+if ${tcl_cv_cc_arch_ppc64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_arch_ppc64=yes
+else
+  tcl_cv_cc_arch_ppc64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5
+$as_echo "$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)
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; }
+if ${tcl_cv_cc_arch_x86_64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_arch_x86_64=yes
+else
+  tcl_cv_cc_arch_x86_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5
+$as_echo "$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;;
+                   *)
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+$as_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}'
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
+$as_echo_n "checking if ld accepts -single_module flag... " >&6; }
+if ${tcl_cv_ld_single_module+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_ld_single_module=yes
+else
+  tcl_cv_ld_single_module=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
+$as_echo "$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 compatibility 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_SUFFIX=".dylib"
+           # 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"
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
+$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; }
+if ${tcl_cv_ld_search_paths_first+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_ld_search_paths_first=yes
+else
+  tcl_cv_ld_search_paths_first=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5
+$as_echo "$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 :
+
+
+$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h
+
+               tcl_cv_cc_visibility_hidden=yes
+
+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 :
+
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit X11" >&5
+$as_echo_n "checking for 64-bit X11... " >&6; }
+if ${tcl_cv_lib_x11_64+:} false; then :
+  $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_lib_x11_64=yes
+else
+  tcl_cv_lib_x11_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_x11_64" >&5
+$as_echo "$tcl_cv_lib_x11_64" >&6; }
+
+fi
+               if test "${TEA_WINDOWINGSYSTEM}" = aqua; then :
+
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit Tk" >&5
+$as_echo_n "checking for 64-bit Tk... " >&6; }
+if ${tcl_cv_lib_tk_64+:} false; then :
+  $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <tk.h>
+int
+main ()
+{
+Tk_InitStubs(NULL, "", 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_lib_tk_64=yes
+else
+  tcl_cv_lib_tk_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_tk_64" >&5
+$as_echo "$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 :
+
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: Removing 64-bit architectures from compiler & linker flags" >&5
+$as_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
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+
+$as_echo "#define _OE_SOCKETS 1" >>confdefs.h
+
+           ;;
+       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_SUFFIX=".so"
+           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"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           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"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       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.
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_SUFFIX=".so"
+           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.
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+
+           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 :
+
+                           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+$as_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";;
+                           *)
+                               { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_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
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+fi
+fi
+
+fi
+
+           SHLIB_SUFFIX=".so"
+           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"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5
+$as_echo_n "checking for ld accepts -Bexport flag... " >&6; }
+if ${tcl_cv_ld_Bexport+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_ld_Bexport=yes
+else
+  tcl_cv_ld_Bexport=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5
+$as_echo "$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 :
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+
+fi
+
+
+
+    # Add in the arch flags late to ensure it wasn't removed.
+    # Not necessary in TEA, but this is aligned with core
+    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 "$GCC" = yes; then :
+
+       case $system in
+           AIX-*) ;;
+           BSD/OS*) ;;
+           CYGWIN_*|MINGW32_*) ;;
+           IRIX*) ;;
+           NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+           Darwin-*) ;;
+           SCO_SV-3.2*) ;;
+           windows) ;;
+           *) SHLIB_CFLAGS="-fPIC" ;;
+       esac
+fi
+
+    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
+
+
+$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
+
+
+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
+
+    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
+$as_echo_n "checking for SEH support in compiler... " >&6; }
+if ${tcl_cv_seh+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  tcl_cv_seh=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+           int main(int argc, char** argv) {
+               int a, b = 0;
+               __try {
+                   a = 666 / b;
+               }
+               __except (EXCEPTION_EXECUTE_HANDLER) {
+                   return 0;
+               }
+               return 1;
+           }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  tcl_cv_seh=yes
+else
+  tcl_cv_seh=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
+$as_echo "$tcl_cv_seh" >&6; }
+       if test "$tcl_cv_seh" = "no" ; then
+
+$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h
+
+       fi
+
+       #
+       # Check to see if the excpt.h include file provided contains the
+       # definition for EXCEPTION_DISPOSITION; if not, which is the case
+       # with Cygwin's version as of 2002-04-10, define it to be int,
+       # sufficient for getting the current code to work.
+       #
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
+$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
+if ${tcl_cv_eh_disposition+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#          define WIN32_LEAN_AND_MEAN
+#          include <windows.h>
+#          undef WIN32_LEAN_AND_MEAN
+
+int
+main ()
+{
+
+               EXCEPTION_DISPOSITION x;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_eh_disposition=yes
+else
+  tcl_cv_eh_disposition=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
+$as_echo "$tcl_cv_eh_disposition" >&6; }
+       if test "$tcl_cv_eh_disposition" = "no" ; then
+
+$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h
+
+       fi
+
+       # Check to see if winnt.h defines CHAR, SHORT, and LONG
+       # even if VOID has already been #defined. The win32api
+       # used by mingw and cygwin is known to do this.
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
+$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; }
+if ${tcl_cv_winnt_ignore_void+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+int
+main ()
+{
+
+               CHAR c;
+               SHORT s;
+               LONG l;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_winnt_ignore_void=yes
+else
+  tcl_cv_winnt_ignore_void=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5
+$as_echo "$tcl_cv_winnt_ignore_void" >&6; }
+       if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+
+$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h
+
+       fi
+    fi
+
+       # See if the compiler supports casting to a union type.
+       # This is used to stop gcc from printing a compiler
+       # warning when initializing a union member.
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
+$as_echo_n "checking for cast to union support... " >&6; }
+if ${tcl_cv_cast_to_union+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+                 union foo { int i; double d; };
+                 union foo f = (union foo) (int) 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_cast_to_union=yes
+else
+  tcl_cv_cast_to_union=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
+$as_echo "$tcl_cv_cast_to_union" >&6; }
+       if test "$tcl_cv_cast_to_union" = "yes"; then
+
+$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
+
+       fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5
+$as_echo_n "checking for required early compiler flags... " >&6; }
+    tcl_flags=""
+
+    if ${tcl_cv_flag__isoc99_source+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__isoc99_source=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__isoc99_source=yes
+else
+  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
+
+$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h
+
+       tcl_flags="$tcl_flags _ISOC99_SOURCE"
+    fi
+
+
+    if ${tcl_cv_flag__largefile64_source+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile64_source=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile64_source=yes
+else
+  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
+
+$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
+
+       tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+    fi
+
+
+    if ${tcl_cv_flag__largefile_source64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile_source64=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile_source64=yes
+else
+  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
+
+$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h
+
+       tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+    fi
+
+    if test "x${tcl_flags}" = "x" ; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
+$as_echo "${tcl_flags}" >&6; }
+    fi
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5
+$as_echo_n "checking for 64-bit integer type... " >&6; }
+    if ${tcl_cv_type_64bit+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_type_64bit=__int64
+else
+  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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+switch (0) {
+            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+        }
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_type_64bit=${tcl_type_64bit}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "${tcl_cv_type_64bit}" = none ; then
+
+$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: using long" >&5
+$as_echo "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*
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Tcl header defaults" >&5
+$as_echo "using Tcl header defaults" >&6; }
+    else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5
+$as_echo "${tcl_cv_type_64bit}" >&6; }
+
+       # Now check for auxiliary declarations
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
+$as_echo_n "checking for struct dirent64... " >&6; }
+if ${tcl_cv_struct_dirent64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_struct_dirent64=yes
+else
+  tcl_cv_struct_dirent64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
+$as_echo "$tcl_cv_struct_dirent64" >&6; }
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
+
+       fi
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
+$as_echo_n "checking for struct stat64... " >&6; }
+if ${tcl_cv_struct_stat64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_struct_stat64=yes
+else
+  tcl_cv_struct_stat64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
+$as_echo "$tcl_cv_struct_stat64" >&6; }
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
+
+       fi
+
+       for ac_func in open64 lseek64
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
+$as_echo_n "checking for off64_t... " >&6; }
+       if ${tcl_cv_type_off64_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_type_off64_t=yes
+else
+  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
+
+$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h
+
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       else
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+       fi
+    fi
+
+
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
+$as_echo_n "checking for build with symbols... " >&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} -DNDEBUG"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
+$as_echo "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
+
+$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h
+
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem debugging" >&5
+$as_echo "enabled symbols mem debugging" >&6; }
+       else
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
+$as_echo "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.
+#--------------------------------------------------------------------
+
+
+$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
+
+
+#--------------------------------------------------------------------
+# Enable compile-time support for TIP #143 and TIP #285.  When using
+# a pre-Tcl 8.5 or 8.6 core, respectively, the actual functionality
+# will not be available at runtime.
+#--------------------------------------------------------------------
+
+
+$as_echo "#define TCL_TIP143 1" >>confdefs.h
+
+
+$as_echo "#define TCL_TIP285 1" >>confdefs.h
+
+
+#--------------------------------------------------------------------
+# 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)"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "manifest needed" >/dev/null 2>&1; then :
+
+       # Could do a CHECK_PROG for mt, but should always be with MSVC8+
+       VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;2 ; fi"
+       VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;1 ; fi"
+       MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
+
+    CLEANFILES="$CLEANFILES *.manifest"
+
+
+fi
+rm -f conftest*
+
+       MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -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.
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test "$GCC" = "yes"; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+           if test "$GCC" = "yes"; then
+               PKG_LIB_FILE=lib${PKG_LIB_FILE}
+           fi
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${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_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${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.
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
+$as_echo_n "checking for tclsh... " >&6; }
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+          if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}"
+          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}" ; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}"
+          fi
+        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
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${TCLSH_PROG}" >&5
+$as_echo "${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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; 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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+       cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+         mv -f confcache "$cache_file"$$ &&
+         mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+         mv -f confcache "$cache_file" ;;
+       esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_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='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+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=
+U=
+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=`$as_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.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $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}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## 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=:
+  # Pre-4.2 versions of Zsh do 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_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+       expr "X$arg" : "X\\(.*\\)$as_nl";
+       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+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.)
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+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
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+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
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# 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
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='        ';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+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 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_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 ||
+$as_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" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by thread $as_me 2.8.0, which was
+generated by GNU Autoconf 2.69.  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
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   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 the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+thread config.status 2.8.0
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+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=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    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 )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_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.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append 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 || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# 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" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = "\a"
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[        ]*=[    ]*/{
+h
+s///
+s/^/:/
+s/[     ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[  ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[      ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[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="$ac_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 ||
+          as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append 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 '`
+         $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+       `' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    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 ||
+$as_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"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_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
+  #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# 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=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  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 || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;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
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# 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 || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
similarity index 95%
rename from pkgs/thread2.7.3/configure.ac
rename to pkgs/thread2.8.0/configure.ac
index ebb3d04..fbbc65d 100755 (executable)
@@ -17,7 +17,7 @@ dnl   to configure the system for the local environment.
 # so you can encode the package version directly into the source files.
 #-----------------------------------------------------------------------
 
-AC_INIT([thread], [2.7.3])
+AC_INIT([thread], [2.8.0])
 
 #--------------------------------------------------------------------
 # Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -76,6 +76,13 @@ TEA_SETUP_COMPILER
 TCLTHREAD_WITH_GDBM
 
 #--------------------------------------------------------------------
+# Check if building with optional lmdb package. This will declare
+# LMDB_CFLAGS and LMDB_LIBS variables.
+#--------------------------------------------------------------------
+
+TCLTHREAD_WITH_LMDB
+
+#--------------------------------------------------------------------
 # Locate the NaviServer/AOLserver dir for compilation as NaviServer/AOLserver module.
 # This will declare NS_INCLUDES, NS_LIBS and define NS_AOLSERVER.
 #--------------------------------------------------------------------
@@ -98,6 +105,7 @@ TEA_ADD_SOURCES([generic/threadNs.c           \
                  generic/threadSpCmd.c        \
                  generic/threadPoolCmd.c      \
                  generic/psGdbm.c             \
+                 generic/psLmdb.c             \
                  generic/threadSvListCmd.c    \
                  generic/threadSvKeylistCmd.c \
                  generic/tclXkeylist.c        \
@@ -105,8 +113,8 @@ TEA_ADD_SOURCES([generic/threadNs.c           \
 
 TEA_ADD_HEADERS([generic/tclThread.h])
 TEA_ADD_INCLUDES([${NS_INCLUDES}])
-TEA_ADD_LIBS([${GDBM_LIBS} ${NS_LIBS}])
-TEA_ADD_CFLAGS([${GDBM_CFLAGS}])
+TEA_ADD_LIBS([${GDBM_LIBS} ${LMDB_LIBS} ${NS_LIBS}])
+TEA_ADD_CFLAGS([${GDBM_CFLAGS} ${LMDB_CFLAGS}])
 TEA_ADD_STUB_SOURCES([])
 TEA_ADD_TCL_SOURCES([lib/ttrace.tcl])
 
diff --git a/pkgs/thread2.8.0/doc/html/thread.html b/pkgs/thread2.8.0/doc/html/thread.html
new file mode 100644 (file)
index 0000000..6e89dfc
--- /dev/null
@@ -0,0 +1,604 @@
+
+<html><head>
+<title>thread - Tcl Threading</title>
+<style type="text/css"><!--
+    HTML {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    BODY {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    DIV.doctools {
+       margin-left:    10%;
+       margin-right:   10%;
+    }
+    DIV.doctools H1,DIV.doctools H2 {
+       margin-left:    -5%;
+    }
+    H1, H2, H3, H4 {
+       margin-top:     1em;
+       font-family:    sans-serif;
+       font-size:      large;
+       color:          #005A9C;
+       background:     transparent;
+       text-align:             left;
+    }
+    H1.doctools_title {
+       text-align: center;
+    }
+    UL,OL {
+       margin-right: 0em;
+       margin-top: 3pt;
+       margin-bottom: 3pt;
+    }
+    UL LI {
+       list-style: disc;
+    }
+    OL LI {
+       list-style: decimal;
+    }
+    DT {
+       padding-top:    1ex;
+    }
+    UL.doctools_toc,UL.doctools_toc UL, UL.doctools_toc UL UL {
+       font:           normal 12pt/14pt sans-serif;
+       list-style:     none;
+    }
+    LI.doctools_section, LI.doctools_subsection {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    PRE {
+       display:        block;
+       font-family:    monospace;
+       white-space:    pre;
+       margin:         0%;
+       padding-top:    0.5ex;
+       padding-bottom: 0.5ex;
+       padding-left:   1ex;
+       padding-right:  1ex;
+       width:          100%;
+    }
+    PRE.doctools_example {
+       color:          black;
+       background:     #f5dcb3;
+       border:         1px solid black;
+    }
+    UL.doctools_requirements LI, UL.doctools_syntax LI {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    DIV.doctools_synopsis {
+       color:          black;
+       background:     #80ffff;
+       border:         1px solid black;
+       font-family:    serif;
+       margin-top:     1em;
+       margin-bottom:  1em;
+    }
+    UL.doctools_syntax {
+       margin-top:     1em;
+       border-top:     1px solid black;
+    }
+    UL.doctools_requirements {
+       margin-bottom:  1em;
+       border-bottom:  1px solid black;
+    }
+--></style>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- thread.n
+   -->
+<body><div class="doctools">
+<h1 class="doctools_title">thread(n) 2.8  &quot;Tcl Threading&quot;</h1>
+<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
+<p>thread - Extension for script access to Tcl threading</p>
+</div>
+<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
+<ul class="doctools_toc">
+<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
+<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>
+<li class="doctools_section"><a href="#section1">Description</a></li>
+<li class="doctools_section"><a href="#section2">COMMANDS</a></li>
+<li class="doctools_section"><a href="#section3">DISCUSSION</a></li>
+<li class="doctools_section"><a href="#see-also">See Also</a></li>
+<li class="doctools_section"><a href="#keywords">Keywords</a></li>
+</ul>
+</div>
+<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
+<div class="doctools_synopsis">
+<ul class="doctools_requirements">
+<li>package require <b class="pkgname">Tcl 8.4</b></li>
+<li>package require <b class="pkgname">Thread <span class="opt">?2.8?</span></b></li>
+</ul>
+<ul class="doctools_syntax">
+<li><a href="#1"><b class="cmd">thread::create</b> <span class="opt">?-joinable?</span> <span class="opt">?-preserved?</span> <span class="opt">?script?</span></a></li>
+<li><a href="#2"><b class="cmd">thread::preserve</b> <span class="opt">?id?</span></a></li>
+<li><a href="#3"><b class="cmd">thread::release</b> <span class="opt">?-wait?</span> <span class="opt">?id?</span></a></li>
+<li><a href="#4"><b class="cmd">thread::id</b></a></li>
+<li><a href="#5"><b class="cmd">thread::errorproc</b> <span class="opt">?procname?</span></a></li>
+<li><a href="#6"><b class="cmd">thread::cancel</b> <span class="opt">?-unwind?</span> <i class="arg">id</i> <span class="opt">?result?</span></a></li>
+<li><a href="#7"><b class="cmd">thread::unwind</b></a></li>
+<li><a href="#8"><b class="cmd">thread::exit</b> <span class="opt">?status?</span></a></li>
+<li><a href="#9"><b class="cmd">thread::names</b></a></li>
+<li><a href="#10"><b class="cmd">thread::exists</b> <i class="arg">id</i></a></li>
+<li><a href="#11"><b class="cmd">thread::send</b> <span class="opt">?-async?</span> <span class="opt">?-head?</span> <i class="arg">id</i> <i class="arg">script</i> <span class="opt">?varname?</span></a></li>
+<li><a href="#12"><b class="cmd">thread::broadcast</b> <i class="arg">script</i></a></li>
+<li><a href="#13"><b class="cmd">thread::wait</b></a></li>
+<li><a href="#14"><b class="cmd">thread::eval</b> <span class="opt">?-lock mutex?</span> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></li>
+<li><a href="#15"><b class="cmd">thread::join</b> <i class="arg">id</i></a></li>
+<li><a href="#16"><b class="cmd">thread::configure</b> <i class="arg">id</i> <span class="opt">?option?</span> <span class="opt">?value?</span> <span class="opt">?...?</span></a></li>
+<li><a href="#17"><b class="cmd">thread::transfer</b> <i class="arg">id</i> <i class="arg">channel</i></a></li>
+<li><a href="#18"><b class="cmd">thread::detach</b> <i class="arg">channel</i></a></li>
+<li><a href="#19"><b class="cmd">thread::attach</b> <i class="arg">channel</i></a></li>
+<li><a href="#20"><b class="cmd">thread::mutex</b></a></li>
+<li><a href="#21"><b class="cmd">thread::mutex</b> <b class="method">create</b> <span class="opt">?-recursive?</span></a></li>
+<li><a href="#22"><b class="cmd">thread::mutex</b> <b class="method">destroy</b> <i class="arg">mutex</i></a></li>
+<li><a href="#23"><b class="cmd">thread::mutex</b> <b class="method">lock</b> <i class="arg">mutex</i></a></li>
+<li><a href="#24"><b class="cmd">thread::mutex</b> <b class="method">unlock</b> <i class="arg">mutex</i></a></li>
+<li><a href="#25"><b class="cmd">thread::rwmutex</b></a></li>
+<li><a href="#26"><b class="cmd">thread::rwmutex</b> <b class="method">create</b></a></li>
+<li><a href="#27"><b class="cmd">thread::rwmutex</b> <b class="method">destroy</b> <i class="arg">mutex</i></a></li>
+<li><a href="#28"><b class="cmd">thread::rwmutex</b> <b class="method">rlock</b> <i class="arg">mutex</i></a></li>
+<li><a href="#29"><b class="cmd">thread::rwmutex</b> <b class="method">wlock</b> <i class="arg">mutex</i></a></li>
+<li><a href="#30"><b class="cmd">thread::rwmutex</b> <b class="method">unlock</b> <i class="arg">mutex</i></a></li>
+<li><a href="#31"><b class="cmd">thread::cond</b></a></li>
+<li><a href="#32"><b class="cmd">thread::cond</b> <b class="method">create</b></a></li>
+<li><a href="#33"><b class="cmd">thread::cond</b> <b class="method">destroy</b> <i class="arg">cond</i></a></li>
+<li><a href="#34"><b class="cmd">thread::cond</b> <b class="method">notify</b> <i class="arg">cond</i></a></li>
+<li><a href="#35"><b class="cmd">thread::cond</b> <b class="method">wait</b> <i class="arg">cond</i> <i class="arg">mutex</i> <span class="opt">?ms?</span></a></li>
+</ul>
+</div>
+</div>
+<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
+<p>The <b class="package">thread</b> 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.</p>
+</div>
+<div id="section2" class="doctools_section"><h2><a name="section2">COMMANDS</a></h2>
+<p>This section describes commands for creating and destroying threads
+and sending scripts to threads for evaluation.</p>
+<dl class="doctools_definitions">
+<dt><a name="1"><b class="cmd">thread::create</b> <span class="opt">?-joinable?</span> <span class="opt">?-preserved?</span> <span class="opt">?script?</span></a></dt>
+<dd><p>This command creates a thread that contains a Tcl interpreter.
+The Tcl interpreter either evaluates the optional <b class="option">script</b>, 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 <b class="option">script</b> 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).</p>
+<p>If the optional <b class="option">script</b> 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 <b class="option">script</b> the thread will run the <b class="option">script</b> 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.</p>
+<p>Using flag <b class="option">-joinable</b> 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 <b class="option">-joinable</b> flag
+results in resource and memory leaks.</p>
+<p>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 <b class="option">script</b> 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.</p>
+<p>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>
+<pre class="doctools_example">
+    # You should never do ...
+    set tid [thread::create {
+        package require Http
+        thread::wait
+        vwait forever ; # &lt;-- this!
+    }]
+</pre>
+<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!</p>
+<p>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 <b class="option">-preserved</b> 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.</p></dd>
+<dt><a name="2"><b class="cmd">thread::preserve</b> <span class="opt">?id?</span></a></dt>
+<dd><p>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 <b class="option">id</b>, the command preserves
+the given thread. Otherwise the current thread is preserved.</p>
+<p>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.</p></dd>
+<dt><a name="3"><b class="cmd">thread::release</b> <span class="opt">?-wait?</span> <span class="opt">?id?</span></a></dt>
+<dd><p>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 <b class="option">id</b>, 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.</p>
+<p>Optional flag <b class="option">-wait</b> 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
+<b class="option">-wait</b>, 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 <b class="option">-joinable</b> option of the <b class="cmd">thread::create</b>
+command and the <b class="cmd">thread::join</b> to wait for thread to exit.</p></dd>
+<dt><a name="4"><b class="cmd">thread::id</b></a></dt>
+<dd><p>This command returns the ID of the current thread.</p></dd>
+<dt><a name="5"><b class="cmd">thread::errorproc</b> <span class="opt">?procname?</span></a></dt>
+<dd><p>This command sets a handler for errors that occur in scripts sent
+asynchronously, using the <b class="option">-async</b> 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>
+<pre class="doctools_example">
+    myerrorproc thread_id errorInfo
+</pre>
+</dd>
+<dt><a name="6"><b class="cmd">thread::cancel</b> <span class="opt">?-unwind?</span> <i class="arg">id</i> <span class="opt">?result?</span></a></dt>
+<dd><p>This command requires Tcl version 8.6 or higher.</p>
+<p>Cancels the script being evaluated in the thread given by the <i class="arg">id</i>
+parameter. Without the <b class="option">-unwind</b> switch the evaluation stack for
+the interpreter is unwound until an enclosing catch command is found or
+there are no further invocations of the interpreter left on the call
+stack. With the <b class="option">-unwind</b> switch the evaluation stack for the
+interpreter is unwound without regard to any intervening catch command
+until there are no further invocations of the interpreter left on the
+call stack. If <i class="arg">result</i> is present, it will be used as the error
+message string; otherwise, a default error message string will be used.</p></dd>
+<dt><a name="7"><b class="cmd">thread::unwind</b></a></dt>
+<dd><p>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.</p>
+<p>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.</p></dd>
+<dt><a name="8"><b class="cmd">thread::exit</b> <span class="opt">?status?</span></a></dt>
+<dd><p>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.</p>
+<p>This command forces a thread stuck in the <b class="cmd">thread::wait</b> command to
+unconditionaly exit. The thread's exit status defaults to 666 and can be
+specified using the optional <i class="arg">status</i> argument. 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.</p></dd>
+<dt><a name="9"><b class="cmd">thread::names</b></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="10"><b class="cmd">thread::exists</b> <i class="arg">id</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="11"><b class="cmd">thread::send</b> <span class="opt">?-async?</span> <span class="opt">?-head?</span> <i class="arg">id</i> <i class="arg">script</i> <span class="opt">?varname?</span></a></dt>
+<dd><p>This command passes a <i class="arg">script</i> to another thread and, optionally,
+waits for the result. If the <b class="option">-async</b> 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.</p>
+<p>Optional <b class="option">varname</b> specifies name of the variable to store
+the result of the <i class="arg">script</i>. Without the <b class="option">-async</b> flag,
+the command returns the evaluation code, similarily to the standard
+Tcl <b class="cmd">catch</b> command. If, however, the <b class="option">-async</b> flag is
+specified, the command returns immediately and caller can later
+<b class="cmd">vwait</b> on <span class="opt">?varname?</span> to get the result of the passed <i class="arg">script</i></p>
+<pre class="doctools_example">
+    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>
+<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.</p>
+<p>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 <span class="opt">?-head?</span> 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.</p></dd>
+<dt><a name="12"><b class="cmd">thread::broadcast</b> <i class="arg">script</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="13"><b class="cmd">thread::wait</b></a></dt>
+<dd><p>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 past
+the <b class="cmd">thread::wait</b> which is usually not what you want and/or
+expect.</p>
+<pre class="doctools_example">
+    set t1 [thread::create {
+        #
+        # Do some initialization work here
+        #
+        thread::wait ; # Enter the event loop
+    }]
+</pre>
+</dd>
+<dt><a name="14"><b class="cmd">thread::eval</b> <span class="opt">?-lock mutex?</span> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></dt>
+<dd><p>This command concatenates passed arguments and evaluates the
+resulting script under the mutex protection. If no mutex is
+specified by using the <span class="opt">?-lock mutex?</span> optional argument,
+the internal static mutex is used.</p></dd>
+<dt><a name="15"><b class="cmd">thread::join</b> <i class="arg">id</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="16"><b class="cmd">thread::configure</b> <i class="arg">id</i> <span class="opt">?option?</span> <span class="opt">?value?</span> <span class="opt">?...?</span></a></dt>
+<dd><p>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: <b class="option">-eventmark</b> and <b class="option">-unwindonerror</b>.</p>
+<p>The <b class="option">-eventmark</b> 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 <b class="option">-eventmark</b>. Default value for the
+<b class="option">-eventmark</b> is 0 (zero) which effectively disables the checking,
+i.e. allows for unlimited number of posted scripts.</p>
+<p>The <b class="option">-unwindonerror</b> option, when set, causes the
+target thread to unwind if the result of the script processing
+resulted in error. Default value for the <b class="option">-unwindonerror</b>
+is 0 (false), i.e. thread continues to process scripts after one
+of the posted scripts fails.</p></dd>
+<dt><a name="17"><b class="cmd">thread::transfer</b> <i class="arg">id</i> <i class="arg">channel</i></a></dt>
+<dd><p>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.</p>
+<p>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>
+<pre class="doctools_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
+    }
+</pre>
+</dd>
+<dt><a name="18"><b class="cmd">thread::detach</b> <i class="arg">channel</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="19"><b class="cmd">thread::attach</b> <i class="arg">channel</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="20"><b class="cmd">thread::mutex</b></a></dt>
+<dd><p>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.</p>
+<p>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.</p>
+<p>The <b class="cmd">thread::mutex</b> command supports following subcommands and options:</p>
+<dl class="doctools_definitions">
+<dt><a name="21"><b class="cmd">thread::mutex</b> <b class="method">create</b> <span class="opt">?-recursive?</span></a></dt>
+<dd><p>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 <span class="opt">?-recursive?</span> argument was specified, the command
+creates the exclusive mutex. With the <span class="opt">?-recursive?</span> argument,
+the command creates a recursive mutex.</p></dd>
+<dt><a name="22"><b class="cmd">thread::mutex</b> <b class="method">destroy</b> <i class="arg">mutex</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="23"><b class="cmd">thread::mutex</b> <b class="method">lock</b> <i class="arg">mutex</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="24"><b class="cmd">thread::mutex</b> <b class="method">unlock</b> <i class="arg">mutex</i></a></dt>
+<dd><p>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.</p></dd>
+</dl></dd>
+<dt><a name="25"><b class="cmd">thread::rwmutex</b></a></dt>
+<dd><p>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.</p>
+<p>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.</p>
+<p>The <b class="cmd">thread::rwmutex</b> command supports following subcommands and options:</p>
+<dl class="doctools_definitions">
+<dt><a name="26"><b class="cmd">thread::rwmutex</b> <b class="method">create</b></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="27"><b class="cmd">thread::rwmutex</b> <b class="method">destroy</b> <i class="arg">mutex</i></a></dt>
+<dd><p>Destroys the reader/writer <i class="arg">mutex</i>. If the mutex is already locked,
+attempt to destroy it will throw Tcl error.</p></dd>
+<dt><a name="28"><b class="cmd">thread::rwmutex</b> <b class="method">rlock</b> <i class="arg">mutex</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="29"><b class="cmd">thread::rwmutex</b> <b class="method">wlock</b> <i class="arg">mutex</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="30"><b class="cmd">thread::rwmutex</b> <b class="method">unlock</b> <i class="arg">mutex</i></a></dt>
+<dd><p>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.</p></dd>
+</dl></dd>
+<dt><a name="31"><b class="cmd">thread::cond</b></a></dt>
+<dd><p>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.</p>
+<p>The command supports following subcommands and options:</p>
+<dl class="doctools_definitions">
+<dt><a name="32"><b class="cmd">thread::cond</b> <b class="method">create</b></a></dt>
+<dd><p>Creates the condition variable and returns it's opaque handle.
+This handle should be used for any future reference to newly
+created condition variable.</p></dd>
+<dt><a name="33"><b class="cmd">thread::cond</b> <b class="method">destroy</b> <i class="arg">cond</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="34"><b class="cmd">thread::cond</b> <b class="method">notify</b> <i class="arg">cond</i></a></dt>
+<dd><p>Wakes up all threads waiting on the condition variable <i class="arg">cond</i>.</p></dd>
+<dt><a name="35"><b class="cmd">thread::cond</b> <b class="method">wait</b> <i class="arg">cond</i> <i class="arg">mutex</i> <span class="opt">?ms?</span></a></dt>
+<dd><p>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.</p>
+<p>The <b class="option">ms</b> 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.</p>
+<p>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>
+<pre class="doctools_example">
+    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>
+<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).</p></dd>
+</dl></dd>
+</dl>
+</div>
+<div id="section3" class="doctools_section"><h2><a name="section3">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>
+<p>For advanced multithreading scripts, script-level access to two
+basic synchronization primitives, mutex and condition variables,
+is also supported.</p>
+</div>
+<div id="see-also" class="doctools_section"><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</p>
+</div>
+<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
+<p>events, message passing, mutex, synchronization, thread</p>
+</div>
+</div></body></html>
+
diff --git a/pkgs/thread2.8.0/doc/html/tpool.html b/pkgs/thread2.8.0/doc/html/tpool.html
new file mode 100644 (file)
index 0000000..468d7ce
--- /dev/null
@@ -0,0 +1,316 @@
+
+<html><head>
+<title>tpool - Tcl Threading</title>
+<style type="text/css"><!--
+    HTML {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    BODY {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    DIV.doctools {
+       margin-left:    10%;
+       margin-right:   10%;
+    }
+    DIV.doctools H1,DIV.doctools H2 {
+       margin-left:    -5%;
+    }
+    H1, H2, H3, H4 {
+       margin-top:     1em;
+       font-family:    sans-serif;
+       font-size:      large;
+       color:          #005A9C;
+       background:     transparent;
+       text-align:             left;
+    }
+    H1.doctools_title {
+       text-align: center;
+    }
+    UL,OL {
+       margin-right: 0em;
+       margin-top: 3pt;
+       margin-bottom: 3pt;
+    }
+    UL LI {
+       list-style: disc;
+    }
+    OL LI {
+       list-style: decimal;
+    }
+    DT {
+       padding-top:    1ex;
+    }
+    UL.doctools_toc,UL.doctools_toc UL, UL.doctools_toc UL UL {
+       font:           normal 12pt/14pt sans-serif;
+       list-style:     none;
+    }
+    LI.doctools_section, LI.doctools_subsection {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    PRE {
+       display:        block;
+       font-family:    monospace;
+       white-space:    pre;
+       margin:         0%;
+       padding-top:    0.5ex;
+       padding-bottom: 0.5ex;
+       padding-left:   1ex;
+       padding-right:  1ex;
+       width:          100%;
+    }
+    PRE.doctools_example {
+       color:          black;
+       background:     #f5dcb3;
+       border:         1px solid black;
+    }
+    UL.doctools_requirements LI, UL.doctools_syntax LI {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    DIV.doctools_synopsis {
+       color:          black;
+       background:     #80ffff;
+       border:         1px solid black;
+       font-family:    serif;
+       margin-top:     1em;
+       margin-bottom:  1em;
+    }
+    UL.doctools_syntax {
+       margin-top:     1em;
+       border-top:     1px solid black;
+    }
+    UL.doctools_requirements {
+       margin-bottom:  1em;
+       border-bottom:  1px solid black;
+    }
+--></style>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- tpool.n
+   -->
+<body><div class="doctools">
+<h1 class="doctools_title">tpool(n) 2.8  &quot;Tcl Threading&quot;</h1>
+<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
+<p>tpool - Part of the Tcl threading extension implementing pools of worker threads.</p>
+</div>
+<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
+<ul class="doctools_toc">
+<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
+<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>
+<li class="doctools_section"><a href="#section1">Description</a></li>
+<li class="doctools_section"><a href="#section2">COMMANDS</a></li>
+<li class="doctools_section"><a href="#section3">DISCUSSION</a></li>
+<li class="doctools_section"><a href="#see-also">See Also</a></li>
+<li class="doctools_section"><a href="#keywords">Keywords</a></li>
+</ul>
+</div>
+<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
+<div class="doctools_synopsis">
+<ul class="doctools_requirements">
+<li>package require <b class="pkgname">Tcl 8.4</b></li>
+<li>package require <b class="pkgname">Thread <span class="opt">?2.8?</span></b></li>
+</ul>
+<ul class="doctools_syntax">
+<li><a href="#1"><b class="cmd">tpool::create</b> <span class="opt">?options?</span></a></li>
+<li><a href="#2"><b class="cmd">tpool::names</b></a></li>
+<li><a href="#3"><b class="cmd">tpool::post</b> <span class="opt">?-detached?</span> <span class="opt">?-nowait?</span> <i class="arg">tpool</i> <i class="arg">script</i></a></li>
+<li><a href="#4"><b class="cmd">tpool::wait</b> <i class="arg">tpool</i> <i class="arg">joblist</i> <span class="opt">?varname?</span></a></li>
+<li><a href="#5"><b class="cmd">tpool::cancel</b> <i class="arg">tpool</i> <i class="arg">joblist</i> <span class="opt">?varname?</span></a></li>
+<li><a href="#6"><b class="cmd">tpool::get</b> <i class="arg">tpool</i> <i class="arg">job</i></a></li>
+<li><a href="#7"><b class="cmd">tpool::preserve</b> <i class="arg">tpool</i></a></li>
+<li><a href="#8"><b class="cmd">tpool::release</b> <i class="arg">tpool</i></a></li>
+<li><a href="#9"><b class="cmd">tpool::suspend</b> <i class="arg">tpool</i></a></li>
+<li><a href="#10"><b class="cmd">tpool::resume</b> <i class="arg">tpool</i></a></li>
+</ul>
+</div>
+</div>
+<div id="section1" class="doctools_section"><h2><a name="section1">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.</p>
+</div>
+<div id="section2" class="doctools_section"><h2><a name="section2">COMMANDS</a></h2>
+<dl class="doctools_definitions">
+<dt><a name="1"><b class="cmd">tpool::create</b> <span class="opt">?options?</span></a></dt>
+<dd><p>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.</p>
+<p>Following options are supported:</p>
+<dl class="doctools_options">
+<dt><b class="option">-minworkers</b> <i class="arg">number</i></dt>
+<dd><p>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.</p></dd>
+<dt><b class="option">-maxworkers</b> <i class="arg">number</i></dt>
+<dd><p>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.</p></dd>
+<dt><b class="option">-idletime</b> <i class="arg">seconds</i></dt>
+<dd><p>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
+<b class="option">minthreads</b> option, it will exit.
+If an <b class="option">exitscript</b> has been defined, the exiting worker thread
+will first run the script and then exit. Errors from the exit script,
+if any, are ignored.</p>
+<p>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.</p></dd>
+<dt><b class="option">-initcmd</b> <i class="arg">script</i></dt>
+<dd><p>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.</p></dd>
+<dt><b class="option">-exitcmd</b> <i class="arg">script</i></dt>
+<dd><p>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.</p></dd>
+</dl></dd>
+<dt><a name="2"><b class="cmd">tpool::names</b></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="3"><b class="cmd">tpool::post</b> <span class="opt">?-detached?</span> <span class="opt">?-nowait?</span> <i class="arg">tpool</i> <i class="arg">script</i></a></dt>
+<dd><p>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 <span class="opt">?-nowait?</span> 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.</p>
+<p>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 <span class="opt">?-detached?</span> 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.</p>
+<p>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.</p></dd>
+<dt><a name="4"><b class="cmd">tpool::wait</b> <i class="arg">tpool</i> <i class="arg">joblist</i> <span class="opt">?varname?</span></a></dt>
+<dd><p>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.</p>
+<p>The command returns the list of completed job IDs. If the optional variable
+<span class="opt">?varname?</span> 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.</p></dd>
+<dt><a name="5"><b class="cmd">tpool::cancel</b> <i class="arg">tpool</i> <i class="arg">joblist</i> <span class="opt">?varname?</span></a></dt>
+<dd><p>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
+<span class="opt">?varname?</span> 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.</p></dd>
+<dt><a name="6"><b class="cmd">tpool::get</b> <i class="arg">tpool</i> <i class="arg">job</i></a></dt>
+<dd><p>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 <b class="variable">errorInfo</b> and
+<b class="variable">errorCode</b> 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.</p></dd>
+<dt><a name="7"><b class="cmd">tpool::preserve</b> <i class="arg">tpool</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="8"><b class="cmd">tpool::release</b> <i class="arg">tpool</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="9"><b class="cmd">tpool::suspend</b> <i class="arg">tpool</i></a></dt>
+<dd><p>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
+<b class="option">minworkers</b> option of the <b class="cmd">tpool::create</b> command.</p></dd>
+<dt><a name="10"><b class="cmd">tpool::resume</b> <i class="arg">tpool</i></a></dt>
+<dd><p>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.</p></dd>
+</dl>
+</div>
+<div id="section3" class="doctools_section"><h2><a name="section3">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>
+<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.</p>
+</div>
+<div id="see-also" class="doctools_section"><h2><a name="see-also">See Also</a></h2>
+<p>thread, tsv, ttrace</p>
+</div>
+<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
+<p>thread, threadpool</p>
+</div>
+</div></body></html>
+
diff --git a/pkgs/thread2.8.0/doc/html/tsv.html b/pkgs/thread2.8.0/doc/html/tsv.html
new file mode 100644 (file)
index 0000000..6461f5e
--- /dev/null
@@ -0,0 +1,409 @@
+
+<html><head>
+<title>tsv - Tcl Threading</title>
+<style type="text/css"><!--
+    HTML {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    BODY {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    DIV.doctools {
+       margin-left:    10%;
+       margin-right:   10%;
+    }
+    DIV.doctools H1,DIV.doctools H2 {
+       margin-left:    -5%;
+    }
+    H1, H2, H3, H4 {
+       margin-top:     1em;
+       font-family:    sans-serif;
+       font-size:      large;
+       color:          #005A9C;
+       background:     transparent;
+       text-align:             left;
+    }
+    H1.doctools_title {
+       text-align: center;
+    }
+    UL,OL {
+       margin-right: 0em;
+       margin-top: 3pt;
+       margin-bottom: 3pt;
+    }
+    UL LI {
+       list-style: disc;
+    }
+    OL LI {
+       list-style: decimal;
+    }
+    DT {
+       padding-top:    1ex;
+    }
+    UL.doctools_toc,UL.doctools_toc UL, UL.doctools_toc UL UL {
+       font:           normal 12pt/14pt sans-serif;
+       list-style:     none;
+    }
+    LI.doctools_section, LI.doctools_subsection {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    PRE {
+       display:        block;
+       font-family:    monospace;
+       white-space:    pre;
+       margin:         0%;
+       padding-top:    0.5ex;
+       padding-bottom: 0.5ex;
+       padding-left:   1ex;
+       padding-right:  1ex;
+       width:          100%;
+    }
+    PRE.doctools_example {
+       color:          black;
+       background:     #f5dcb3;
+       border:         1px solid black;
+    }
+    UL.doctools_requirements LI, UL.doctools_syntax LI {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    DIV.doctools_synopsis {
+       color:          black;
+       background:     #80ffff;
+       border:         1px solid black;
+       font-family:    serif;
+       margin-top:     1em;
+       margin-bottom:  1em;
+    }
+    UL.doctools_syntax {
+       margin-top:     1em;
+       border-top:     1px solid black;
+    }
+    UL.doctools_requirements {
+       margin-bottom:  1em;
+       border-bottom:  1px solid black;
+    }
+--></style>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- tsv.n
+   -->
+<body><div class="doctools">
+<h1 class="doctools_title">tsv(n) 2.8  &quot;Tcl Threading&quot;</h1>
+<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
+<p>tsv - Part of the Tcl threading extension allowing script level manipulation of data shared between threads.</p>
+</div>
+<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
+<ul class="doctools_toc">
+<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
+<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>
+<li class="doctools_section"><a href="#section1">Description</a></li>
+<li class="doctools_section"><a href="#section2">ELEMENT COMMANDS</a></li>
+<li class="doctools_section"><a href="#section3">LIST COMMANDS</a></li>
+<li class="doctools_section"><a href="#section4">ARRAY COMMANDS</a></li>
+<li class="doctools_section"><a href="#section5">KEYED LIST COMMANDS</a></li>
+<li class="doctools_section"><a href="#section6">DISCUSSION</a></li>
+<li class="doctools_section"><a href="#section7">CREDITS</a></li>
+<li class="doctools_section"><a href="#see-also">See Also</a></li>
+<li class="doctools_section"><a href="#keywords">Keywords</a></li>
+</ul>
+</div>
+<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
+<div class="doctools_synopsis">
+<ul class="doctools_requirements">
+<li>package require <b class="pkgname">Tcl 8.4</b></li>
+<li>package require <b class="pkgname">Thread <span class="opt">?2.8?</span></b></li>
+</ul>
+<ul class="doctools_syntax">
+<li><a href="#1"><b class="cmd">tsv::names</b> <span class="opt">?pattern?</span></a></li>
+<li><a href="#2"><b class="cmd">tsv::object</b> <i class="arg">varname</i> <i class="arg">element</i></a></li>
+<li><a href="#3"><b class="cmd">tsv::set</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?value?</span></a></li>
+<li><a href="#4"><b class="cmd">tsv::get</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?namedvar?</span></a></li>
+<li><a href="#5"><b class="cmd">tsv::unset</b> <i class="arg">varname</i> <span class="opt">?element?</span></a></li>
+<li><a href="#6"><b class="cmd">tsv::exists</b> <i class="arg">varname</i> <i class="arg">element</i></a></li>
+<li><a href="#7"><b class="cmd">tsv::pop</b> <i class="arg">varname</i> <i class="arg">element</i></a></li>
+<li><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></li>
+<li><a href="#9"><b class="cmd">tsv::incr</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?count?</span></a></li>
+<li><a href="#10"><b class="cmd">tsv::append</b> <i class="arg">varname</i> <i class="arg">element</i> <i class="arg">value</i> <span class="opt">?value ...?</span></a></li>
+<li><a href="#11"><b class="cmd">tsv::lock</b> <i class="arg">varname</i> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></li>
+<li><a href="#12"><b class="cmd">tsv::handlers</b></a></li>
+<li><a href="#13"><b class="cmd">tsv::lappend</b> <i class="arg">varname</i> <i class="arg">element</i> <i class="arg">value</i> <span class="opt">?value ...?</span></a></li>
+<li><a href="#14"><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> <span class="opt">?value ...?</span></a></li>
+<li><a href="#15"><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> <span class="opt">?value ...?</span></a></li>
+<li><a href="#16"><b class="cmd">tsv::llength</b> <i class="arg">varname</i> <i class="arg">element</i></a></li>
+<li><a href="#17"><b class="cmd">tsv::lindex</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></li>
+<li><a href="#18"><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></li>
+<li><a href="#19"><b class="cmd">tsv::lsearch</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?options?</span> <i class="arg">pattern</i></a></li>
+<li><a href="#20"><b class="cmd">tsv::lset</b> <i class="arg">varname</i> <i class="arg">element</i> <i class="arg">index</i> <span class="opt">?index ...?</span> <i class="arg">value</i></a></li>
+<li><a href="#21"><b class="cmd">tsv::lpop</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></li>
+<li><a href="#22"><b class="cmd">tsv::lpush</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></li>
+<li><a href="#23"><b class="cmd">tsv::array set</b> <i class="arg">varname</i> <i class="arg">list</i></a></li>
+<li><a href="#24"><b class="cmd">tsv::array get</b> <i class="arg">varname</i> <span class="opt">?pattern?</span></a></li>
+<li><a href="#25"><b class="cmd">tsv::array names</b> <i class="arg">varname</i> <span class="opt">?pattern?</span></a></li>
+<li><a href="#26"><b class="cmd">tsv::array size</b> <i class="arg">varname</i></a></li>
+<li><a href="#27"><b class="cmd">tsv::array reset</b> <i class="arg">varname</i> <i class="arg">list</i></a></li>
+<li><a href="#28"><b class="cmd">tsv::array bind</b> <i class="arg">varname</i> <i class="arg">handle</i></a></li>
+<li><a href="#29"><b class="cmd">tsv::array unbind</b> <i class="arg">varname</i></a></li>
+<li><a href="#30"><b class="cmd">tsv::array isbound</b> <i class="arg">varname</i></a></li>
+<li><a href="#31"><b class="cmd">tsv::keyldel</b> <i class="arg">varname</i> <i class="arg">keylist</i> <i class="arg">key</i></a></li>
+<li><a href="#32"><b class="cmd">tsv::keylget</b> <i class="arg">varname</i> <i class="arg">keylist</i> <i class="arg">key</i> <span class="opt">?retvar?</span></a></li>
+<li><a href="#33"><b class="cmd">tsv::keylkeys</b> <i class="arg">varname</i> <i class="arg">keylist</i> <span class="opt">?key?</span></a></li>
+<li><a href="#34"><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> <span class="opt">?key value..?</span></a></li>
+</ul>
+</div>
+</div>
+<div id="section1" class="doctools_section"><h2><a name="section1">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>
+<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.</p>
+</div>
+<div id="section2" class="doctools_section"><h2><a name="section2">ELEMENT COMMANDS</a></h2>
+<dl class="doctools_definitions">
+<dt><a name="1"><b class="cmd">tsv::names</b> <span class="opt">?pattern?</span></a></dt>
+<dd><p>Returns names of shared variables matching optional <span class="opt">?pattern?</span>
+or all known variables if pattern is ommited.</p></dd>
+<dt><a name="2"><b class="cmd">tsv::object</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
+<dd><p>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>
+<pre class="doctools_example">
+    % 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>
+</dd>
+<dt><a name="3"><b class="cmd">tsv::set</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?value?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="4"><b class="cmd">tsv::get</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?namedvar?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="5"><b class="cmd">tsv::unset</b> <i class="arg">varname</i> <span class="opt">?element?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="6"><b class="cmd">tsv::exists</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="7"><b class="cmd">tsv::pop</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
+<dd><p>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.</p></dd>
+<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></dt>
+<dd><p>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.</p></dd>
+<dt><a name="9"><b class="cmd">tsv::incr</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?count?</span></a></dt>
+<dd><p>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.</p></dd>
+<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> <span class="opt">?value ...?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="11"><b class="cmd">tsv::lock</b> <i class="arg">varname</i> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></dt>
+<dd><p>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>
+<pre class="doctools_example">
+    % tsv::lock foo {
+        tsv::lappend foo bar 1
+        tsv::lappend foo bar 2
+        puts stderr [tsv::set foo bar]
+        tsv::unset foo
+    }
+</pre>
+</dd>
+<dt><a name="12"><b class="cmd">tsv::handlers</b></a></dt>
+<dd><p>Returns the names of all persistent storage handlers enabled at compile time.
+See <span class="sectref"><a href="#section4">ARRAY COMMANDS</a></span> for details.</p></dd>
+</dl>
+</div>
+<div id="section3" class="doctools_section"><h2><a name="section3">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.</p>
+<dl class="doctools_definitions">
+<dt><a name="13"><b class="cmd">tsv::lappend</b> <i class="arg">varname</i> <i class="arg">element</i> <i class="arg">value</i> <span class="opt">?value ...?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="14"><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> <span class="opt">?value ...?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="15"><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> <span class="opt">?value ...?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="16"><b class="cmd">tsv::llength</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="17"><b class="cmd">tsv::lindex</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="18"><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></dt>
+<dd><p>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.</p></dd>
+<dt><a name="19"><b class="cmd">tsv::lsearch</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?options?</span> <i class="arg">pattern</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="20"><b class="cmd">tsv::lset</b> <i class="arg">varname</i> <i class="arg">element</i> <i class="arg">index</i> <span class="opt">?index ...?</span> <i class="arg">value</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="21"><b class="cmd">tsv::lpop</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="22"><b class="cmd">tsv::lpush</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></dt>
+<dd><p>This command performes the opposite of the <b class="cmd">tsv::lpop</b> command.
+As its counterpart, it returns no value to the caller.</p></dd>
+</dl>
+</div>
+<div id="section4" class="doctools_section"><h2><a name="section4">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 persistent
+options supported are the famous GNU Gdbm and LMDB. These options have to be
+selected during the package compilation time.
+The implementation provides hooks for defining other persistency layers, if
+needed.</p>
+<dl class="doctools_definitions">
+<dt><a name="23"><b class="cmd">tsv::array set</b> <i class="arg">varname</i> <i class="arg">list</i></a></dt>
+<dd><p>Does the same as standard Tcl <b class="cmd">array set</b>.</p></dd>
+<dt><a name="24"><b class="cmd">tsv::array get</b> <i class="arg">varname</i> <span class="opt">?pattern?</span></a></dt>
+<dd><p>Does the same as standard Tcl <b class="cmd">array get</b>.</p></dd>
+<dt><a name="25"><b class="cmd">tsv::array names</b> <i class="arg">varname</i> <span class="opt">?pattern?</span></a></dt>
+<dd><p>Does the same as standard Tcl <b class="cmd">array names</b>.</p></dd>
+<dt><a name="26"><b class="cmd">tsv::array size</b> <i class="arg">varname</i></a></dt>
+<dd><p>Does the same as standard Tcl <b class="cmd">array size</b>.</p></dd>
+<dt><a name="27"><b class="cmd">tsv::array reset</b> <i class="arg">varname</i> <i class="arg">list</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="28"><b class="cmd">tsv::array bind</b> <i class="arg">varname</i> <i class="arg">handle</i></a></dt>
+<dd><p>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;, where &lt;handler&gt; is
+&quot;gdbm&quot; for GNU Gdbm and &quot;lmdb&quot; for LMDB and &lt;address&gt; is the path to the
+database file.</p></dd>
+<dt><a name="29"><b class="cmd">tsv::array unbind</b> <i class="arg">varname</i></a></dt>
+<dd><p>Unbinds the shared <i class="arg">array</i> from its bound persistent storage.</p></dd>
+<dt><a name="30"><b class="cmd">tsv::array isbound</b> <i class="arg">varname</i></a></dt>
+<dd><p>Returns true (1) if the shared <i class="arg">varname</i> is bound to some
+persistent storage or zero (0) if not.</p></dd>
+</dl>
+</div>
+<div id="section5" class="doctools_section"><h2><a name="section5">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>
+<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>
+<pre class="doctools_example">
+    {{NAME  {Frank  Zappa}} {JOB {musician and composer}}}
+</pre>
+<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>
+<pre class="doctools_example">
+    {ID 106} {NAME {{FIRST Frank} {LAST Zappa}}}
+</pre>
+<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.</p>
+<dl class="doctools_definitions">
+<dt><a name="31"><b class="cmd">tsv::keyldel</b> <i class="arg">varname</i> <i class="arg">keylist</i> <i class="arg">key</i></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="32"><b class="cmd">tsv::keylget</b> <i class="arg">varname</i> <i class="arg">keylist</i> <i class="arg">key</i> <span class="opt">?retvar?</span></a></dt>
+<dd><p>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.</p>
+<p>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.</p></dd>
+<dt><a name="33"><b class="cmd">tsv::keylkeys</b> <i class="arg">varname</i> <i class="arg">keylist</i> <span class="opt">?key?</span></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="34"><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> <span class="opt">?key value..?</span></a></dt>
+<dd><p>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.</p></dd>
+</dl>
+</div>
+<div id="section6" class="doctools_section"><h2><a name="section6">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>
+<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.</p>
+</div>
+<div id="section7" class="doctools_section"><h2><a name="section7">CREDITS</a></h2>
+<p>Thread shared variables are inspired by the nsv interface found in
+AOLserver, a highly scalable Web server from America Online.</p>
+</div>
+<div id="see-also" class="doctools_section"><h2><a name="see-also">See Also</a></h2>
+<p>thread, tpool, ttrace</p>
+</div>
+<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
+<p>locking, synchronization, thread shared data, threads</p>
+</div>
+</div></body></html>
+
diff --git a/pkgs/thread2.8.0/doc/html/ttrace.html b/pkgs/thread2.8.0/doc/html/ttrace.html
new file mode 100644 (file)
index 0000000..d767719
--- /dev/null
@@ -0,0 +1,312 @@
+
+<html><head>
+<title>ttrace - Tcl Threading</title>
+<style type="text/css"><!--
+    HTML {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    BODY {
+       background:     #FFFFFF;
+       color:          black;
+    }
+    DIV.doctools {
+       margin-left:    10%;
+       margin-right:   10%;
+    }
+    DIV.doctools H1,DIV.doctools H2 {
+       margin-left:    -5%;
+    }
+    H1, H2, H3, H4 {
+       margin-top:     1em;
+       font-family:    sans-serif;
+       font-size:      large;
+       color:          #005A9C;
+       background:     transparent;
+       text-align:             left;
+    }
+    H1.doctools_title {
+       text-align: center;
+    }
+    UL,OL {
+       margin-right: 0em;
+       margin-top: 3pt;
+       margin-bottom: 3pt;
+    }
+    UL LI {
+       list-style: disc;
+    }
+    OL LI {
+       list-style: decimal;
+    }
+    DT {
+       padding-top:    1ex;
+    }
+    UL.doctools_toc,UL.doctools_toc UL, UL.doctools_toc UL UL {
+       font:           normal 12pt/14pt sans-serif;
+       list-style:     none;
+    }
+    LI.doctools_section, LI.doctools_subsection {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    PRE {
+       display:        block;
+       font-family:    monospace;
+       white-space:    pre;
+       margin:         0%;
+       padding-top:    0.5ex;
+       padding-bottom: 0.5ex;
+       padding-left:   1ex;
+       padding-right:  1ex;
+       width:          100%;
+    }
+    PRE.doctools_example {
+       color:          black;
+       background:     #f5dcb3;
+       border:         1px solid black;
+    }
+    UL.doctools_requirements LI, UL.doctools_syntax LI {
+       list-style:     none;
+       margin-left:    0em;
+       text-indent:    0em;
+       padding:        0em;
+    }
+    DIV.doctools_synopsis {
+       color:          black;
+       background:     #80ffff;
+       border:         1px solid black;
+       font-family:    serif;
+       margin-top:     1em;
+       margin-bottom:  1em;
+    }
+    UL.doctools_syntax {
+       margin-top:     1em;
+       border-top:     1px solid black;
+    }
+    UL.doctools_requirements {
+       margin-bottom:  1em;
+       border-bottom:  1px solid black;
+    }
+--></style>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- ttrace.n
+   -->
+<body><div class="doctools">
+<h1 class="doctools_title">ttrace(n) 2.8  &quot;Tcl Threading&quot;</h1>
+<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
+<p>ttrace - Trace-based interpreter initialization</p>
+</div>
+<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
+<ul class="doctools_toc">
+<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
+<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>
+<li class="doctools_section"><a href="#section1">Description</a></li>
+<li class="doctools_section"><a href="#section2">USER COMMANDS</a></li>
+<li class="doctools_section"><a href="#section3">CALLBACK COMMANDS</a></li>
+<li class="doctools_section"><a href="#section4">DISCUSSION</a></li>
+<li class="doctools_section"><a href="#see-also">See Also</a></li>
+<li class="doctools_section"><a href="#keywords">Keywords</a></li>
+</ul>
+</div>
+<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
+<div class="doctools_synopsis">
+<ul class="doctools_requirements">
+<li>package require <b class="pkgname">Tcl 8.4</b></li>
+<li>package require <b class="pkgname">Thread <span class="opt">?2.8?</span></b></li>
+</ul>
+<ul class="doctools_syntax">
+<li><a href="#1"><b class="cmd">ttrace::eval</b> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></li>
+<li><a href="#2"><b class="cmd">ttrace::enable</b></a></li>
+<li><a href="#3"><b class="cmd">ttrace::disable</b></a></li>
+<li><a href="#4"><b class="cmd">ttrace::cleanup</b></a></li>
+<li><a href="#5"><b class="cmd">ttrace::update</b> <span class="opt">?epoch?</span></a></li>
+<li><a href="#6"><b class="cmd">ttrace::getscript</b></a></li>
+<li><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></li>
+<li><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></li>
+<li><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></li>
+<li><a href="#10"><b class="cmd">ttrace::addscript</b> <i class="arg">name</i> <i class="arg">body</i></a></li>
+<li><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></li>
+<li><a href="#12"><b class="cmd">ttrace::addcleanup</b> <i class="arg">body</i></a></li>
+<li><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></li>
+<li><a href="#14"><b class="cmd">ttrace::getentry</b> <i class="arg">cmd</i> <i class="arg">var</i></a></li>
+<li><a href="#15"><b class="cmd">ttrace::getentries</b> <i class="arg">cmd</i> <span class="opt">?pattern?</span></a></li>
+<li><a href="#16"><b class="cmd">ttrace::delentry</b> <i class="arg">cmd</i></a></li>
+<li><a href="#17"><b class="cmd">ttrace::preload</b> <i class="arg">cmd</i></a></li>
+</ul>
+</div>
+</div>
+<div id="section1" class="doctools_section"><h2><a name="section1">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>
+<p>The package requires Tcl threading extension but can be alternatively
+used stand-alone within the AOLserver, a scalable webserver from
+America Online.</p>
+<p>In a nutshell, a short sample illustrating the usage of the ttrace
+with the Tcl threading extension:</p>
+<pre class="doctools_example">
+    % package require Ttrace
+    2.8.0
+    % 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>
+<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.</p>
+</div>
+<div id="section2" class="doctools_section"><h2><a name="section2">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.</p>
+<dl class="doctools_definitions">
+<dt><a name="1"><b class="cmd">ttrace::eval</b> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></dt>
+<dd><p>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.</p>
+<p>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.</p></dd>
+<dt><a name="2"><b class="cmd">ttrace::enable</b></a></dt>
+<dd><p>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.</p></dd>
+<dt><a name="3"><b class="cmd">ttrace::disable</b></a></dt>
+<dd><p>Deactivates all registered callbacks in the framework
+and closes the current trace epoch.</p></dd>
+<dt><a name="4"><b class="cmd">ttrace::cleanup</b></a></dt>
+<dd><p>Used to clean-up all on-demand loaded resources in the interpreter.
+It effectively brings Tcl interpreter to its pristine state.</p></dd>
+<dt><a name="5"><b class="cmd">ttrace::update</b> <span class="opt">?epoch?</span></a></dt>
+<dd><p>Used to refresh the state of the interpreter to match the optional
+trace <span class="opt">?epoch?</span>. If the optional <span class="opt">?epoch?</span> is not given, it takes
+the most recent trace epoch.</p></dd>
+<dt><a name="6"><b class="cmd">ttrace::getscript</b></a></dt>
+<dd><p>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>.</p></dd>
+</dl>
+</div>
+<div id="section3" class="doctools_section"><h2><a name="section3">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>
+<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.</p>
+<dl class="doctools_definitions">
+<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></dt>
+<dd><p>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.</p></dd>
+<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></dt>
+<dd><p>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.</p></dd>
+<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></dt>
+<dd><p>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.</p></dd>
+<dt><a name="10"><b class="cmd">ttrace::addscript</b> <i class="arg">name</i> <i class="arg">body</i></a></dt>
+<dd><p>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.</p></dd>
+<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></dt>
+<dd><p>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.</p></dd>
+<dt><a name="12"><b class="cmd">ttrace::addcleanup</b> <i class="arg">body</i></a></dt>
+<dd><p>Registers Tcl callback to be activated by the <b class="cmd">trace::cleanup</b>.
+Registered callbacks are activated on FIFO basis.</p></dd>
+<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></dt>
+<dd><p>Adds one entry to the named in-memory database.</p></dd>
+<dt><a name="14"><b class="cmd">ttrace::getentry</b> <i class="arg">cmd</i> <i class="arg">var</i></a></dt>
+<dd><p>Returns the value of the entry from the named in-memory database.</p></dd>
+<dt><a name="15"><b class="cmd">ttrace::getentries</b> <i class="arg">cmd</i> <span class="opt">?pattern?</span></a></dt>
+<dd><p>Returns names of all entries from the named in-memory database.</p></dd>
+<dt><a name="16"><b class="cmd">ttrace::delentry</b> <i class="arg">cmd</i></a></dt>
+<dd><p>Deletes an entry from the named in-memory database.</p></dd>
+<dt><a name="17"><b class="cmd">ttrace::preload</b> <i class="arg">cmd</i></a></dt>
+<dd><p>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.</p></dd>
+</dl>
+</div>
+<div id="section4" class="doctools_section"><h2><a name="section4">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>
+<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.</p>
+</div>
+<div id="see-also" class="doctools_section"><h2><a name="see-also">See Also</a></h2>
+<p>thread, tpool, tsv</p>
+</div>
+<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
+<p>command tracing, introspection</p>
+</div>
+</div></body></html>
+
similarity index 51%
rename from pkgs/thread2.7.3/doc/man/thread.n
rename to pkgs/thread2.8.0/doc/man/thread.n
index afd3fb8..4b5f1cc 100644 (file)
@@ -1,73 +1,81 @@
 '\"
 '\" 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.
-'\"
-'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.TH "thread" n 2\&.8  "Tcl Threading"
+.\" The -*- nroff -*- 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 ?manpage?
+.\"    Start of list of standard options for a Tk widget. The manpage
+.\"    argument defines where to look up the standard options; if
+.\"    omitted, defaults to "options". The options follow on successive
+.\"    lines, in three 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.
+.\"
+.\" .QW arg1 ?arg2?
+.\"    Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\"    Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\"    (for trailing punctuation) and then a closing parenthesis.
+.\"
+.\"    # 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
+.\"    # Start an argument description
 .de AP
 .ie !"\\$4"" .TP \\$4
 .el \{\
@@ -76,7 +84,7 @@
 .\}
 .ta \\n()Au \\n()Bu
 .ie !"\\$3"" \{\
-\&\\$1 \\fI\\$2\\fP    (\\$3)
+\&\\$1 \\fI\\$2\\fP (\\$3)
 .\".b
 .\}
 .el \{\
@@ -89,7 +97,7 @@
 .\}
 .\}
 ..
-'\"    # define tabbing values for .AP
+.\"    # define tabbing values for .AP
 .de AS
 .nr )A 10n
 .if !"\\$1"" .nr )A \\w'\\$1'u+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
+.\"    # BS - start boxed text
+.\"    # ^y = starting y location
+.\"    # ^b = 1
 .de BS
 .br
 .mk ^y
 .if n \l'\\n(.lu\(ul'
 .if n .fi
 ..
-'\"    # BE - end boxed text (draw box now)
+.\"    # BE - end boxed text (draw box now)
 .de BE
 .nf
 .ti 0
 .br
 .nr ^b 0
 ..
-'\"    # VS - start vertical sidebar
-'\"    # ^Y = starting y location
-'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.\"    # 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
+.\"    # VE - end of vertical sidebar
 .de VE
 .ie n 'mc
 .el \{\
 .\}
 .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.
+.\"    # 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
 .mk ^Y
 .\}
 ..
-'\"    # DS - begin display
+.\"    # DS - begin display
 .de DS
 .RS
 .nf
 .sp
 ..
-'\"    # DE - end display
+.\"    # DE - end display
 .de DE
 .fi
 .RE
 .sp
 ..
-'\"    # SO - start of list of standard options
+.\"    # SO - start of list of standard options
 .de SO
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
 .SH "STANDARD OPTIONS"
 .LP
 .nf
 .ta 5.5c 11c
 .ft B
 ..
-'\"    # SE - end of list of standard options
+.\"    # 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.
+See the \\*(So manual entry for details on the standard options.
 ..
-'\"    # OP - start of full description for a single option
+.\"    # OP - start of full description for a single option
 .de OP
 .LP
 .nf
@@ -222,31 +232,50 @@ Database Class:   \\fB\\$3\\fR
 .fi
 .IP
 ..
-'\"    # CS - begin code excerpt
+.\"    # CS - begin code excerpt
 .de CS
 .RS
 .nf
 .ta .25i .5i .75i 1i
-.if t .ft C
 ..
-'\"    # CE - end code excerpt
+.\"    # CE - end code excerpt
 .de CE
 .fi
-.if t .ft R
 .RE
 ..
+.\"    # UL - underline word
 .de UL
 \\$1\l'|0\(ul'\\$2
 ..
-
-.TH "thread" n 2.7  "Tcl Threading"
+.\"    # QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\"    # PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\"    # QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\"    # MT - "empty" string
+.de MT
+.QW ""
+..
 .BS
-.SH "NAME"
+.SH NAME
 thread \- Extension for script access to Tcl threading
-.SH "SYNOPSIS"
-package require \fBTcl  8.4\fR
+.SH SYNOPSIS
+package require \fBTcl  8\&.4\fR
 .sp
-package require \fBThread  ?2.7?\fR
+package require \fBThread  ?2\&.8?\fR
 .sp
 \fBthread::create\fR ?-joinable? ?-preserved? ?script?
 .sp
@@ -258,9 +287,11 @@ package require \fBThread  ?2.7?\fR
 .sp
 \fBthread::errorproc\fR ?procname?
 .sp
+\fBthread::cancel\fR ?-unwind? \fIid\fR ?result?
+.sp
 \fBthread::unwind\fR
 .sp
-\fBthread::exit\fR
+\fBthread::exit\fR ?status?
 .sp
 \fBthread::names\fR
 .sp
@@ -268,15 +299,15 @@ package require \fBThread  ?2.7?\fR
 .sp
 \fBthread::send\fR ?-async? ?-head? \fIid\fR \fIscript\fR ?varname?
 .sp
-\fBthread::broadcast\fR \fIid\fR \fIscript\fR
+\fBthread::broadcast\fR \fIscript\fR
 .sp
 \fBthread::wait\fR
 .sp
-\fBthread::eval\fR ?-lock mutex? \fIarg\fR ?arg ...?
+\fBthread::eval\fR ?-lock mutex? \fIarg\fR ?arg \&.\&.\&.?
 .sp
 \fBthread::join\fR \fIid\fR
 .sp
-\fBthread::configure\fR \fIid\fR ?option? ?value? ?...?
+\fBthread::configure\fR \fIid\fR ?option? ?value? ?\&.\&.\&.?
 .sp
 \fBthread::transfer\fR \fIid\fR \fIchannel\fR
 .sp
@@ -317,194 +348,217 @@ package require \fBThread  ?2.7?\fR
 \fBthread::cond\fR \fBwait\fR \fIcond\fR \fImutex\fR ?ms?
 .sp
 .BE
-.SH "DESCRIPTION"
+.SH DESCRIPTION
 The \fBthread\fR extension creates threads that contain Tcl
 interpreters, and it lets you send scripts to those threads for
-evaluation.
+evaluation\&.
 Additionaly, it provides script-level access to basic thread
-synchronization primitives, like mutexes and condition variables.
-.SH "COMMANDS"
+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.
+and sending scripts to threads for evaluation\&.
 .TP
 \fBthread::create\fR ?-joinable? ?-preserved? ?script?
-This command creates a thread that contains a Tcl interpreter.
+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 \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
+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).
+(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
+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
+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.
+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.
+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.
+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
+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
+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.
+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 ...
+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:
+.CS
+
+
+    # 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.
+
+.CE
+.IP
+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,
+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
+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
+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
+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
+\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.
+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.
+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.
+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
+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.
+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).
+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.
+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.
+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.
+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.
+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
+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.
+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.
+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.
+\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
+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
+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
+.CS
+
+
     myerrorproc thread_id errorInfo
-.fi
+
+.CE
+.TP
+\fBthread::cancel\fR ?-unwind? \fIid\fR ?result?
+This command requires Tcl version 8\&.6 or higher\&.
+.sp
+Cancels the script being evaluated in the thread given by the \fIid\fR
+parameter\&. Without the \fB-unwind\fR switch the evaluation stack for
+the interpreter is unwound until an enclosing catch command is found or
+there are no further invocations of the interpreter left on the call
+stack\&. With the \fB-unwind\fR switch the evaluation stack for the
+interpreter is unwound without regard to any intervening catch command
+until there are no further invocations of the interpreter left on the
+call stack\&. If \fIresult\fR is present, it will be used as the error
+message string; otherwise, a default error message string will be used\&.
 .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.
+\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
+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
+\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.
+situations\&.
 .TP
-\fBthread::exit\fR
+\fBthread::exit\fR ?status?
 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.
+\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 thread's exit status defaults to 666 and can be
+specified using the optional \fIstatus\fR argument\&. 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.
+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.
+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.
+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.
+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
+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.
+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 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
+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
+.CS
+
+
     set t1 [thread::create]
     set t2 [thread::create]
     thread::send -async $t1 "set a 1" result
@@ -512,97 +566,104 @@ specified, the command returns immediately and caller can later
     for {set i 0} {$i < 2} {incr i} {
         vwait result
     }
-.fi
+
+.CE
+.IP
 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,
+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.
+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
+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.
+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.
+thus being executed in the LIFO fashion\&.
 .TP
-\fBthread::broadcast\fR \fIid\fR \fIscript\fR
+\fBthread::broadcast\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.
+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::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 past
 the \fBthread::wait\fR which is usually not what you want and/or
-expect.
-.nf
+expect\&.
+.CS
+
+
     set t1 [thread::create {
         #
         # Do some initialization work here
         #
         thread::wait ; # Enter the event loop
     }]
-.fi
+
+.CE
 .TP
-\fBthread::eval\fR ?-lock mutex? \fIarg\fR ?arg ...?
+\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
+resulting script under the mutex protection\&. If no mutex is
 specified by using the ?-lock mutex? optional argument,
-the internal static mutex is used.
+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.
+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.
+should not be used any more\&.
 .TP
-\fBthread::configure\fR \fIid\fR ?option? ?value? ?...?
+\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.
+\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.
+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
+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.
+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.
+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
+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.
+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
+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.
+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
+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.
+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
+.CS
+
+
     socket -server _Accept 2200
     proc _Accept {s ipaddr port} {
         after idle [list Accept $s $ipaddr $port]
@@ -611,156 +672,159 @@ out of the \fBsocket\fR commands callback procedures:
         set tid [thread::create]
         thread::transfer $tid $s
     }
-.fi
+
+.CE
 .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.
+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.
+\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
+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
+do nothing\&. Command throws error if the \fIchannel\fR cannot be
 found in the list of detached channels and/or in the current
-interpreter.
+interpreter\&.
 .TP
 \fBthread::mutex\fR
-Mutexes are most common thread synchronization primitives.
+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
+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
+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.
+released, which would lead to various deadlock situations\&.
 .sp
-Care has to be taken when using mutexes in an multithreading program.
+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.
+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.
+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.
+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.
+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
+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
+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.
+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.
+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.
+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.
+exclusive or recursive mutexes\&.
 .sp
-For reading the resource, thread should obtain a read lock on the resource.
+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.
+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.
+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.
+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.
+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.
+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.
+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.
+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.
+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.
+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.
+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
+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.
+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.
+Creates the condition variable and returns it's opaque handle\&.
 This handle should be used for any future reference to newly
-created condition variable.
+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.
+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.
+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.
+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.
+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.
+\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.
+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.
+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
+.CS
+
+
     set mutex [thread::mutex create]
     set cond  [thread::cond  create]
 
@@ -770,30 +834,33 @@ evaluates to true:
     }
     # Do some work under mutex protection
     thread::mutex unlock $mutex
-.fi
+
+.CE
+.IP
 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).
+thread wake-ups, for example)\&.
 .RE
-.SH "DISCUSSION"
+.PP
+.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.
+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
+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.
+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
+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.
+\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.
+is also supported\&.
 .SH "SEE ALSO"
-\fIhttp://www.tcl.tk/doc/howto/thread_model.html\fR, tpool, tsv, ttrace
-.SH "KEYWORDS"
+\fIhttp://www\&.tcl\&.tk/doc/howto/thread_model\&.html\fR, tpool, tsv, ttrace
+.SH KEYWORDS
 events, message passing, mutex, synchronization, thread
diff --git a/pkgs/thread2.8.0/doc/man/tpool.n b/pkgs/thread2.8.0/doc/man/tpool.n
new file mode 100644 (file)
index 0000000..a915bcb
--- /dev/null
@@ -0,0 +1,496 @@
+'\"
+'\" Generated from file '' by tcllib/doctools with format 'nroff'
+'\"
+.TH "tpool" n 2\&.8  "Tcl Threading"
+.\" The -*- nroff -*- 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 ?manpage?
+.\"    Start of list of standard options for a Tk widget. The manpage
+.\"    argument defines where to look up the standard options; if
+.\"    omitted, defaults to "options". The options follow on successive
+.\"    lines, in three 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.
+.\"
+.\" .QW arg1 ?arg2?
+.\"    Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\"    Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\"    (for trailing punctuation) and then a closing parenthesis.
+.\"
+.\"    # 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
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
+.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 \\*(So 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
+..
+.\"    # UL - underline word
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+.\"    # QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\"    # PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\"    # QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\"    # MT - "empty" string
+.de MT
+.QW ""
+..
+.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\&.8?\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
+\fBtpool::suspend\fR \fItpool\fR
+.sp
+\fBtpool::resume\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
+\fB-minworkers\fR \fInumber\fR
+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
+\fB-maxworkers\fR \fInumber\fR
+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
+\fB-idletime\fR \fIseconds\fR
+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\&.
+.TP
+\fB-initcmd\fR \fIscript\fR
+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
+\fB-exitcmd\fR \fIscript\fR
+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\&.
+.TP
+\fBtpool::suspend\fR \fItpool\fR
+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
+\fBminworkers\fR option of the \fBtpool::create\fR command\&.
+.TP
+\fBtpool::resume\fR \fItpool\fR
+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\&.
+.PP
+.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
similarity index 54%
rename from pkgs/thread2.7.3/doc/man/tsv.n
rename to pkgs/thread2.8.0/doc/man/tsv.n
index 09a5bb3..386e904 100644 (file)
@@ -1,73 +1,81 @@
 '\"
 '\" 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.
-'\"
-'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.TH "tsv" n 2\&.8  "Tcl Threading"
+.\" The -*- nroff -*- 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 ?manpage?
+.\"    Start of list of standard options for a Tk widget. The manpage
+.\"    argument defines where to look up the standard options; if
+.\"    omitted, defaults to "options". The options follow on successive
+.\"    lines, in three 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.
+.\"
+.\" .QW arg1 ?arg2?
+.\"    Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\"    Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\"    (for trailing punctuation) and then a closing parenthesis.
+.\"
+.\"    # 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
+.\"    # Start an argument description
 .de AP
 .ie !"\\$4"" .TP \\$4
 .el \{\
@@ -76,7 +84,7 @@
 .\}
 .ta \\n()Au \\n()Bu
 .ie !"\\$3"" \{\
-\&\\$1 \\fI\\$2\\fP    (\\$3)
+\&\\$1 \\fI\\$2\\fP (\\$3)
 .\".b
 .\}
 .el \{\
@@ -89,7 +97,7 @@
 .\}
 .\}
 ..
-'\"    # define tabbing values for .AP
+.\"    # define tabbing values for .AP
 .de AS
 .nr )A 10n
 .if !"\\$1"" .nr )A \\w'\\$1'u+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
+.\"    # BS - start boxed text
+.\"    # ^y = starting y location
+.\"    # ^b = 1
 .de BS
 .br
 .mk ^y
 .if n \l'\\n(.lu\(ul'
 .if n .fi
 ..
-'\"    # BE - end boxed text (draw box now)
+.\"    # BE - end boxed text (draw box now)
 .de BE
 .nf
 .ti 0
 .br
 .nr ^b 0
 ..
-'\"    # VS - start vertical sidebar
-'\"    # ^Y = starting y location
-'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.\"    # 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
+.\"    # VE - end of vertical sidebar
 .de VE
 .ie n 'mc
 .el \{\
 .\}
 .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.
+.\"    # 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
 .mk ^Y
 .\}
 ..
-'\"    # DS - begin display
+.\"    # DS - begin display
 .de DS
 .RS
 .nf
 .sp
 ..
-'\"    # DE - end display
+.\"    # DE - end display
 .de DE
 .fi
 .RE
 .sp
 ..
-'\"    # SO - start of list of standard options
+.\"    # SO - start of list of standard options
 .de SO
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
 .SH "STANDARD OPTIONS"
 .LP
 .nf
 .ta 5.5c 11c
 .ft B
 ..
-'\"    # SE - end of list of standard options
+.\"    # 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.
+See the \\*(So manual entry for details on the standard options.
 ..
-'\"    # OP - start of full description for a single option
+.\"    # OP - start of full description for a single option
 .de OP
 .LP
 .nf
@@ -222,33 +232,50 @@ Database Class:   \\fB\\$3\\fR
 .fi
 .IP
 ..
-'\"    # CS - begin code excerpt
+.\"    # CS - begin code excerpt
 .de CS
 .RS
 .nf
 .ta .25i .5i .75i 1i
-.if t .ft C
 ..
-'\"    # CE - end code excerpt
+.\"    # CE - end code excerpt
 .de CE
 .fi
-.if t .ft R
 .RE
 ..
+.\"    # UL - underline word
 .de UL
 \\$1\l'|0\(ul'\\$2
 ..
-
-.TH "tsv" n 2.7  "Tcl Threading"
+.\"    # QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\"    # PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\"    # QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\"    # MT - "empty" string
+.de MT
+.QW ""
+..
 .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
+.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.7?\fR
+package require \fBThread  ?2\&.8?\fR
 .sp
 \fBtsv::names\fR ?pattern?
 .sp
@@ -268,15 +295,17 @@ package require \fBThread  ?2.7?\fR
 .sp
 \fBtsv::incr\fR \fIvarname\fR \fIelement\fR ?count?
 .sp
-\fBtsv::append\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value ...?
+\fBtsv::append\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value \&.\&.\&.?
+.sp
+\fBtsv::lock\fR \fIvarname\fR \fIarg\fR ?arg \&.\&.\&.?
 .sp
-\fBtsv::lock\fR \fIvarname\fR \fIarg\fR ?arg ...?
+\fBtsv::handlers\fR
 .sp
-\fBtsv::lappend\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value ...?
+\fBtsv::lappend\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value \&.\&.\&.?
 .sp
-\fBtsv::linsert\fR \fIvarname\fR \fIelement\fR \fIindex\fR \fIvalue\fR ?value ...?
+\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 ...?
+\fBtsv::lreplace\fR \fIvarname\fR \fIelement\fR \fIfirst\fR \fIlast\fR ?value \&.\&.\&.?
 .sp
 \fBtsv::llength\fR \fIvarname\fR \fIelement\fR
 .sp
@@ -286,7 +315,7 @@ package require \fBThread  ?2.7?\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
+\fBtsv::lset\fR \fIvarname\fR \fIelement\fR \fIindex\fR ?index \&.\&.\&.? \fIvalue\fR
 .sp
 \fBtsv::lpop\fR \fIvarname\fR \fIelement\fR ?index?
 .sp
@@ -314,266 +343,286 @@ package require \fBThread  ?2.7?\fR
 .sp
 \fBtsv::keylkeys\fR \fIvarname\fR \fIkeylist\fR ?key?
 .sp
-\fBtsv::keylset\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR \fIvalue\fR ?key value..?
+\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.
+.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
+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.
+about locking the variable himself\&.
 .PP
-Thread shared variables are not bound to any thread explicitly. That
+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.
+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.
+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.
+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
+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
+the element object command\&. The object command is automatically
+deleted when the element which this command is pointing to is unset\&.
+.CS
+
+
     % tsv::set foo bar "A shared string"
     % set string [tsv::object foo bar]
     % $string append " appended"
     => A shared string appended
-.fi
+
+.CE
 .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
+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.
+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.
+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.
+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
+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.
+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.
+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.
+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.
+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.
+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.
+the Tcl variable\&.
 .TP
-\fBtsv::append\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value ...?
+\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.
+Tcl variable\&.
 .TP
-\fBtsv::lock\fR \fIvarname\fR \fIarg\fR ?arg ...?
+\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
+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
+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\&.
+.CS
+
+
     % tsv::lock foo {
         tsv::lappend foo bar 1
         tsv::lappend foo bar 2
         puts stderr [tsv::set foo bar]
         tsv::unset foo
     }
-.fi
+
+.CE
+.TP
+\fBtsv::handlers\fR
+Returns the names of all persistent storage handlers enabled at compile time\&.
+See \fBARRAY COMMANDS\fR for details\&.
+.PP
 .SH "LIST COMMANDS"
-Those command are similar to the equivalently named Tcl command. The difference
-is that they operate on elements of shared arrays.
+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 ...?
+\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.
+instead of the Tcl variable\&.
 .TP
-\fBtsv::linsert\fR \fIvarname\fR \fIelement\fR \fIindex\fR \fIvalue\fR ?value ...?
+\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.
+\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 ...?
+\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.
+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.
+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.
+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.
+\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.
+in the shared variable \fIvarname\fR instead of the Tcl variable\&.
 .TP
-\fBtsv::lset\fR \fIvarname\fR \fIelement\fR \fIindex\fR ?index ...? \fIvalue\fR
+\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.
+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.
+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.
+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.
+This command performes the opposite of the \fBtsv::lpop\fR command\&.
+As its counterpart, it returns no value to the caller\&.
+.PP
 .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.
+\fBarray\fR command\&. In addition to those, it allows binding
+a shared variable to some persisten storage databases\&. Currently the persistent
+options supported are the famous GNU Gdbm and LMDB\&. These options have 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.
+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.
+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.
+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.
+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.
+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.
+Binds the \fIvarname\fR to the persistent storage \fIhandle\fR\&.
+The format of the \fIhandle\fR is <handler>:<address>, where <handler> is
+"gdbm" for GNU Gdbm and "lmdb" for LMDB and <address> is the path to the
+database file\&.
 .TP
 \fBtsv::array unbind\fR \fIvarname\fR
-Unbinds the shared \fIarray\fR from its bound persistent storage.
+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.
+persistent storage or zero (0) if not\&.
+.PP
 .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.
+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
+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
+.CS
+
+
     {{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
+
+.CE
+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
+NAME\&.FIRST and NAME\&.LAST:
+.CS
+
+
     {ID 106} {NAME {{FIRST Frank} {LAST Zappa}}}
-.fi
+
+.CE
 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
+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.
+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.
+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.
+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.
+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
+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.
+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.
+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..?
+\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"
+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\&.
+.PP
+.SH DISCUSSION
 The current implementation of thread shared variables allows for easy and
-convenient access to data shared between different threads.
+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
+improving performance\&. Special care has been taken to assure that all
 object data is properly locked and deep-copied when moving objects between
-threads.
+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"
+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.
+AOLserver, a highly scalable Web server from America Online\&.
 .SH "SEE ALSO"
 thread, tpool, ttrace
-.SH "KEYWORDS"
+.SH KEYWORDS
 locking, synchronization, thread shared data, threads
similarity index 52%
rename from pkgs/thread2.7.3/doc/man/ttrace.n
rename to pkgs/thread2.8.0/doc/man/ttrace.n
index 5ef5af4..e326acd 100644 (file)
@@ -1,73 +1,81 @@
 '\"
 '\" 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.
-'\"
-'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.TH "ttrace" n 2\&.8  "Tcl Threading"
+.\" The -*- nroff -*- 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 ?manpage?
+.\"    Start of list of standard options for a Tk widget. The manpage
+.\"    argument defines where to look up the standard options; if
+.\"    omitted, defaults to "options". The options follow on successive
+.\"    lines, in three 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.
+.\"
+.\" .QW arg1 ?arg2?
+.\"    Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\"    Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\"    (for trailing punctuation) and then a closing parenthesis.
+.\"
+.\"    # 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
+.\"    # Start an argument description
 .de AP
 .ie !"\\$4"" .TP \\$4
 .el \{\
@@ -76,7 +84,7 @@
 .\}
 .ta \\n()Au \\n()Bu
 .ie !"\\$3"" \{\
-\&\\$1 \\fI\\$2\\fP    (\\$3)
+\&\\$1 \\fI\\$2\\fP (\\$3)
 .\".b
 .\}
 .el \{\
@@ -89,7 +97,7 @@
 .\}
 .\}
 ..
-'\"    # define tabbing values for .AP
+.\"    # define tabbing values for .AP
 .de AS
 .nr )A 10n
 .if !"\\$1"" .nr )A \\w'\\$1'u+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
+.\"    # BS - start boxed text
+.\"    # ^y = starting y location
+.\"    # ^b = 1
 .de BS
 .br
 .mk ^y
 .if n \l'\\n(.lu\(ul'
 .if n .fi
 ..
-'\"    # BE - end boxed text (draw box now)
+.\"    # BE - end boxed text (draw box now)
 .de BE
 .nf
 .ti 0
 .br
 .nr ^b 0
 ..
-'\"    # VS - start vertical sidebar
-'\"    # ^Y = starting y location
-'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.\"    # 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
+.\"    # VE - end of vertical sidebar
 .de VE
 .ie n 'mc
 .el \{\
 .\}
 .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.
+.\"    # 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
 .mk ^Y
 .\}
 ..
-'\"    # DS - begin display
+.\"    # DS - begin display
 .de DS
 .RS
 .nf
 .sp
 ..
-'\"    # DE - end display
+.\"    # DE - end display
 .de DE
 .fi
 .RE
 .sp
 ..
-'\"    # SO - start of list of standard options
+.\"    # SO - start of list of standard options
 .de SO
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
 .SH "STANDARD OPTIONS"
 .LP
 .nf
 .ta 5.5c 11c
 .ft B
 ..
-'\"    # SE - end of list of standard options
+.\"    # 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.
+See the \\*(So manual entry for details on the standard options.
 ..
-'\"    # OP - start of full description for a single option
+.\"    # OP - start of full description for a single option
 .de OP
 .LP
 .nf
@@ -222,33 +232,52 @@ Database Class:   \\fB\\$3\\fR
 .fi
 .IP
 ..
-'\"    # CS - begin code excerpt
+.\"    # CS - begin code excerpt
 .de CS
 .RS
 .nf
 .ta .25i .5i .75i 1i
-.if t .ft C
 ..
-'\"    # CE - end code excerpt
+.\"    # CE - end code excerpt
 .de CE
 .fi
-.if t .ft R
 .RE
 ..
+.\"    # UL - underline word
 .de UL
 \\$1\l'|0\(ul'\\$2
 ..
-
-.TH "ttrace" n 2.7  "Tcl Threading"
+.\"    # QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\"    # PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\"    # QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\"    # MT - "empty" string
+.de MT
+.QW ""
+..
 .BS
-.SH "NAME"
+.SH NAME
 ttrace \- Trace-based interpreter initialization
-.SH "SYNOPSIS"
-package require \fBTcl  8.4\fR
+.SH SYNOPSIS
+package require \fBTcl  8\&.4\fR
 .sp
-package require \fBThread  ?2.7?\fR
+package require \fBThread  ?2\&.8?\fR
 .sp
-\fBttrace::eval\fR \fIarg\fR ?arg ...?
+\fBttrace::eval\fR \fIarg\fR ?arg \&.\&.\&.?
 .sp
 \fBttrace::enable\fR
 .sp
@@ -283,22 +312,24 @@ package require \fBThread  ?2.7?\fR
 \fBttrace::preload\fR \fIcmd\fR
 .sp
 .BE
-.SH "DESCRIPTION"
+.SH DESCRIPTION
 This package creates a framework for on-demand replication of the
-interpreter state accross threads in an multithreading application.
+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.
+\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.
+America Online\&.
 .PP
 In a nutshell, a short sample illustrating the usage of the ttrace
 with the Tcl threading extension:
-.nf
+.CS
+
+
 
     % package require Ttrace
-    2.7.0
+    2\&.8\&.0
 
     % set t1 [thread::create {package require Ttrace; thread::wait}]
     tid0x1802800
@@ -313,160 +344,163 @@ with the Tcl threading extension:
     % thread::send $t2 test
     test-tid0x1804000
 
-.fi
+
+.CE
 .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.
+or later created, threads\&.
 .SH "USER COMMANDS"
-This section describes user-level commands. Those commands can be
+This section describes user-level commands\&. Those commands can be
 used by script writers to control the execution of the tracing
-framework.
+framework\&.
 .TP
-\fBttrace::eval\fR \fIarg\fR ?arg ...?
+\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
+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.
+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.
+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
+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.
+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.
+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.
+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.
+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.
+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.
+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
+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.
+\fBttrace::eval\fR and \fBttrace::update\fR\&.
+.PP
 .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.
+\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.
+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
+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.
+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
+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.
+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
+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.
+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
+\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,
+\fIarglist\fR and the \fIbody\fR of the callback\&. Effectively,
 this actually resembles the call interface of the standard Tcl
-\fBproc\fR command.
+\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.
+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.
+\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.
+\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.
+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.
+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.
+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.
+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.
+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.
+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.
+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"
+\fBunknown\fR command\&.
+.PP
+.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
+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
+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.
+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.
+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
+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
+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.
+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.
+replicated from the master to other Tcl thread/interpreters\&.
 .SH "SEE ALSO"
 thread, tpool, tsv
-.SH "KEYWORDS"
+.SH KEYWORDS
 command tracing, introspection
similarity index 83%
rename from pkgs/thread2.7.3/doc/thread.man
rename to pkgs/thread2.8.0/doc/thread.man
index bc66da9..fa1aaa5 100644 (file)
@@ -1,16 +1,16 @@
 [comment {-*- tcl -*- doctools manpage}]
-[manpage_begin thread n 2.7]
+[manpage_begin thread n 2.8]
 [moddesc {Tcl Threading}]
 [titledesc {Extension for script access to Tcl threading}]
 [require Tcl 8.4]
-[require Thread [opt 2.7]]
+[require Thread [opt 2.8]]
 
 [description]
-The [package thread] extension creates threads that contain Tcl 
+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 
+Additionaly, it provides script-level access to basic thread
 synchronization primitives, like mutexes and condition variables.
 
 [section COMMANDS]
@@ -23,7 +23,7 @@ and sending scripts to threads for evaluation.
 
 [call [cmd thread::create] [opt -joinable] [opt -preserved] [opt script]]
 
-This command creates a thread that contains a Tcl interpreter. 
+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
@@ -38,28 +38,28 @@ automatically when thread is marked for exit
 
 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 
+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.
 
 [para]
 
 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. 
+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. 
+results in resource and memory leaks.
 
 
 [para]
 
-Threads created by the [cmd thread::create] cannot be destroyed 
+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 
+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.
@@ -67,10 +67,10 @@ case, the thread will exit.
 [para]
 
 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 
+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 
+exit. This is considered to be a bad practice and should be avoided
 if possible. This is best illustrated by the example below:
 
 [example {
@@ -84,67 +84,67 @@ if possible. This is best illustrated by the example below:
 
 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 
+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!
 
 [para]
 
-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 
+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. 
+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. 
+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.
 
 [para]
 
-With reference counting, one can implement controlled access to a 
-shared Tcl thread. By incrementing the reference counter, the 
+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 
+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). 
+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 
+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. 
+[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 
+more. Any following reference to the same thread handle will result
 in Tcl error.
 
 [para]
 
-Optional flag [option -wait] instructs the caller thread to wait for 
-the target thread to exit, if the effect of the command would result 
+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 
+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. 
+command and the [cmd thread::join] to wait for thread to exit.
 
 [call [cmd thread::id]]
 
@@ -152,9 +152,9 @@ 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 
+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
@@ -187,32 +187,33 @@ message string; otherwise, a default error message string will be used.
 [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] 
+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.
 [para]
 This command stops a prior [cmd thread::wait] command. Execution of
-the script passed to newly created thread will continue from the 
+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]]
+[call [cmd thread::exit] [opt status]]
 
 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] 
+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.
 [para]
-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.
+This command forces a thread stuck in the [cmd thread::wait] command to
+unconditionaly exit. The thread's exit status defaults to 666 and can be
+specified using the optional [arg status] argument. 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]]
 
@@ -224,7 +225,7 @@ are not reported by this command.
 
 [call [cmd thread::exists] [arg id]]
 
-Returns true (1) if thread given by the [arg id] parameter exists, 
+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.
 
@@ -232,28 +233,28 @@ 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 
+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 
+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. 
+command, like [cmd update], [cmd vwait], etc.
 
 [para]
 
 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 
+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 
+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] 
+    set t2 [thread::create]
     thread::send -async $t1 "set a 1" result
-    thread::send -async $t2 "set b 2" result 
+    thread::send -async $t2 "set b 2" result
     for {set i 0} {$i < 2} {incr i} {
         vwait result
     }
@@ -261,14 +262,14 @@ specified, the command returns immediately and caller can later
 
 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 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.
 
 [para]
 
-Many threads can simultaneously send scripts to the target thread for 
-execution. All of them are entered into the event queue of the target 
+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
@@ -276,7 +277,7 @@ 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]]
+[call [cmd thread::broadcast] [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
@@ -284,7 +285,7 @@ the threads.
 
 [call [cmd thread::wait]]
 
-This enters the event loop so a thread can receive messages from 
+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,
@@ -303,7 +304,7 @@ expect.
 
 [call [cmd thread::eval] [opt {-lock mutex}] [arg arg] [opt {arg ...}]]
 
-This command concatenates passed arguments and evaluates the 
+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.
@@ -321,24 +322,24 @@ 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 
+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].
 
 [para]
 
-The [option -eventmark] option, when set, limits the number of 
-asynchronously posted scripts to the thread event loop. 
+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 
+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.
 
 [para]
 
-The [option -unwindonerror] option, when set, causes the 
-target thread to unwind if the result of the script processing 
+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.
@@ -346,24 +347,24 @@ 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 
+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 
+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 
+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.
 
 [para]
 
-Due to the internal Tcl core implementation and the restriction on 
+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:
@@ -381,7 +382,7 @@ out of the [cmd socket] commands callback procedures:
 
 [call [cmd thread::detach] [arg channel]]
 
-This detaches the specified [arg channel] from the current thread and 
+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].
@@ -391,7 +392,7 @@ Restrictions: same as for transferring shared channels with the
 [call [cmd thread::attach] [arg channel]]
 
 This attaches the previously detached [arg channel] in the
-current thread/interpreter. For already existing channels, 
+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
@@ -401,17 +402,17 @@ 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 
+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.
 [para]
 Care has to be taken when using mutexes in an multithreading program.
-Improper use of mutexes may lead to various deadlock situations, 
+Improper use of mutexes may lead to various deadlock situations,
 especially when using exclusive mutexes.
 
 [para]
@@ -431,16 +432,16 @@ 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. 
+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 
+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. 
+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]]
 
@@ -454,10 +455,10 @@ Attempt to unlock the already unlocked mutex will throw Tcl error.
 [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. 
+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.
 [para]
 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
@@ -466,7 +467,7 @@ 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. 
+again.
 
 [para]
 
@@ -477,7 +478,7 @@ The [cmd thread::rwmutex] command supports following subcommands and options:
 [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 
+This handle should be used for any future reference to the newly
 created mutex.
 
 [call [cmd thread::rwmutex] [method destroy] [arg mutex]]
@@ -508,11 +509,11 @@ Attempt to unlock already unlocked [arg mutex] will throw Tcl error.
 [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 
+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 
+to use other type of mutex in conjuction with the condition
 variable, a Tcl error will be thrown.
 
 [para]
@@ -524,13 +525,13 @@ The command supports following subcommands and options:
 [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 
+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, 
+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]]
@@ -543,15 +544,15 @@ 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 
+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.
 
 [para]
 
 The [option ms] command option, if given, must be an integer specifying
-time interval in milliseconds the command waits to be signalled. 
+time interval in milliseconds the command waits to be signalled.
 Otherwise the command waits on condition notify forever.
 
 [para]
@@ -574,8 +575,8 @@ evaluates to true:
     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 
+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]
@@ -589,11 +590,11 @@ 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 
+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, 
+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.
 
similarity index 93%
rename from pkgs/thread2.7.3/doc/tpool.man
rename to pkgs/thread2.8.0/doc/tpool.man
index 9649e71..51d65d1 100644 (file)
@@ -1,15 +1,15 @@
 [comment {-*- tcl -*- doctools manpage}]
-[manpage_begin tpool n 2.7]
+[manpage_begin tpool n 2.8]
 [moddesc {Tcl Threading}]
 [titledesc {Part of the Tcl threading extension implementing pools of worker threads.}]
 [require Tcl 8.4]
-[require Thread [opt 2.7]]
+[require Thread [opt 2.8]]
 
 [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 
+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 
+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.
@@ -45,10 +45,10 @@ 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 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 
+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.
 
@@ -57,25 +57,25 @@ 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, 
+[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.
 [para]
 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 
+[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.
 
 [opt_def -initcmd [arg 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, 
+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 
+Default value for this option is unspecified, hence, the Tcl interpreter of
 the worker thread will contain just the initial set of Tcl commands.
 
 [opt_def -exitcmd [arg script]]
@@ -87,22 +87,22 @@ on the worker thread exit.
 
 [list_end]
 
-[para] 
+[para]
 
 [call [cmd tpool::names]]
 
-This command returns a list of IDs of threadpools created with the 
+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 
+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 
+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
@@ -112,8 +112,8 @@ and return immediately.
 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 
+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.
 [para]
 If the threadpool [arg tpool] is not found in the list of active
@@ -128,8 +128,8 @@ specified jobs are ready, the command will enter the event loop, service
 events and wait for the first job to get ready.
 [para]
 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] 
+[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]]
@@ -139,15 +139,15 @@ 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] 
+[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, 
+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.
@@ -157,18 +157,18 @@ 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 
+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. 
+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 
+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.
@@ -180,15 +180,15 @@ 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 
+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) 
+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 
+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]
@@ -198,23 +198,23 @@ posted to the pool's work queue.
 
 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 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 
+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 
+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, 
+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 
+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.
 
similarity index 91%
rename from pkgs/thread2.7.3/doc/tsv.man
rename to pkgs/thread2.8.0/doc/tsv.man
index 2ccace2..547cc35 100644 (file)
@@ -1,23 +1,23 @@
 [comment {-*- tcl -*- doctools manpage}]
-[manpage_begin tsv n 2.7]
+[manpage_begin tsv n 2.8]
 [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.7]]
+[require Thread [opt 2.8]]
 
 [description]
 This section describes commands implementing thread shared variables.
-A thread shared variable is very similar to a Tcl array but in 
+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 
+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 
+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 
+User has to explicitly unset the variable to reclaim the memory
 consumed by the variable.
 
 [section {ELEMENT COMMANDS}]
@@ -26,13 +26,13 @@ consumed by the variable.
 
 [call [cmd tsv::names] [opt pattern]]
 
-Returns names of shared variables matching optional [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 
+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.
@@ -46,20 +46,20 @@ deleted when the element which this command is pointing to is unset.
 
 [call [cmd tsv::set] [arg varname] [arg element] [opt value]]
 
-Sets the value of the [arg element] in the shared variable [arg varname] 
+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 
+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 
+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 
+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]]
@@ -86,13 +86,13 @@ 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 
+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 
+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 ...}]]
@@ -114,6 +114,11 @@ created if it did not exists at the time of the first lock operation.
     }
 }]
 
+[call [cmd tsv::handlers]]
+
+Returns the names of all persistent storage handlers enabled at compile time.
+See [sectref {ARRAY COMMANDS}] for details.
+
 [list_end]
 
 [section {LIST COMMANDS}]
@@ -126,25 +131,25 @@ is that they operate on elements of shared arrays.
 [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] 
+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 
+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 
+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 
+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.
 
@@ -174,8 +179,8 @@ in the shared variable [arg varname] instead of the Tcl variable.
 
 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 
+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]]
@@ -189,11 +194,11 @@ As its counterpart, it returns no value to the caller.
 
 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.
+a shared variable to some persisten storage databases. Currently the persistent
+options supported are the famous GNU Gdbm and LMDB. These options have to be
+selected during the package compilation time.
+The implementation provides hooks for defining other persistency layers, if
+needed.
 
 [list_begin definitions]
 
@@ -220,15 +225,15 @@ 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.
+The format of the [arg handle] is <handler>:<address>, where <handler> is
+"gdbm" for GNU Gdbm and "lmdb" for LMDB and <address> is the path to the
+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 
+Returns true (1) if the shared [arg varname] is bound to some
 persistent storage or zero (0) if not.
 
 
@@ -240,9 +245,9 @@ 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 
+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 
+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:
 
@@ -250,9 +255,9 @@ keyed list:
     {{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 
+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 {
@@ -261,8 +266,8 @@ NAME.FIRST and NAME.LAST:
 
 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 
+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]
@@ -277,29 +282,29 @@ This removes both the key and the value from the keyed list.
 
 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 
+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.
 [para]
-If [arg retvar] is specified and [arg key] is in the list, then the value 
+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 
+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 
+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. 
+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 
+exists, [arg value] replaces the existing value. Multiple keywords and
 values may be specified, if desired.
 
 [list_end]
@@ -310,18 +315,18 @@ 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 
+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 
+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, 
+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 
+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]
similarity index 89%
rename from pkgs/thread2.7.3/doc/ttrace.man
rename to pkgs/thread2.8.0/doc/ttrace.man
index fd2dd1e..287fe1e 100644 (file)
@@ -1,18 +1,18 @@
 [comment {-*- tcl -*- doctools manpage}]
-[manpage_begin ttrace n 2.7]
+[manpage_begin ttrace n 2.8]
 [moddesc {Tcl Threading}]
 [titledesc {Trace-based interpreter initialization}]
 [require Tcl 8.4]
-[require Thread [opt 2.7]]
+[require Thread [opt 2.8]]
 
 [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 
+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 
+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
@@ -21,7 +21,7 @@ with the Tcl threading extension:
 [example {
 
     % package require Ttrace
-    2.7.0
+    2.8.0
 
     % set t1 [thread::create {package require Ttrace; thread::wait}]
     tid0x1802800
@@ -39,7 +39,7 @@ with the Tcl threading extension:
 }]
 [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 
+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.
 
@@ -55,16 +55,16 @@ framework.
 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. 
+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 
+the extension are automatically updated. If the command execution
 resulted in Tcl error, no state propagation takes place.
 [para]
 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, 
+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]]
@@ -80,12 +80,12 @@ and closes the current trace epoch.
 
 [call [cmd ttrace::cleanup]]
 
-Used to clean-up all on-demand loaded resources in the interpreter. 
+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 
+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.
 
@@ -100,13 +100,13 @@ is automatically invoked by other higher-level commands like
 [list_end]
 
 [section {CALLBACK COMMANDS}]
-A word upfront: the package already includes callbacks for tracing 
+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 
+[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 
+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
@@ -140,11 +140,11 @@ 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 
+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.
 
 
@@ -162,7 +162,7 @@ The callback definition includes the name of the callback,
 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 
+This callback is used to resolve the resource and load the
 resource in the current interpreter.
 
 [call [cmd ttrace::addcleanup] [arg body]]
@@ -176,7 +176,7 @@ 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. 
+Returns the value of the entry from the named in-memory database.
 
 [call [cmd ttrace::getentries] [arg cmd] [opt pattern]]
 
@@ -189,7 +189,7 @@ 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 
+Commands registered this way will always be the part of
 the interpreter and not be on-demand loaded by the Tcl
 [cmd unknown] command.
 
@@ -199,19 +199,19 @@ the interpreter and not be on-demand loaded by the Tcl
 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], 
+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 
+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 
+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
@@ -220,7 +220,7 @@ 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 
+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]
similarity index 99%
rename from pkgs/thread2.7.3/generic/psGdbm.c
rename to pkgs/thread2.8.0/generic/psGdbm.c
index 6f29ca7..fcaad37 100644 (file)
@@ -347,8 +347,10 @@ ps_gdbm_delete(
  */
 static void
 ps_gdbm_free(
-    void   *data)
+    ClientData handle,
+    void        *data)
 {
+    (void)handle;
     free(data);
 }
 \f
diff --git a/pkgs/thread2.8.0/generic/psLmdb.c b/pkgs/thread2.8.0/generic/psLmdb.c
new file mode 100644 (file)
index 0000000..90900e6
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * This file implements wrappers for persistent lmdb 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifdef HAVE_LMDB
+
+#include "threadSvCmd.h"
+#include <lmdb.h>
+
+/*
+ * Structure keeping the lmdb environment context
+ */
+typedef struct {
+    MDB_env    * env; // Environment
+    MDB_txn    * txn; // Last active read transaction
+    MDB_cursor * cur; // Cursor used for ps_lmdb_first and ps_lmdb_next
+    MDB_dbi      dbi; // Open database (default db)
+    int          err; // Last error (used in ps_lmdb_geterr)
+} * LmdbCtx;
+
+/*
+ * Transaction and DB open mode
+ */
+enum LmdbOpenMode { LmdbRead, LmdbWrite };
+
+// Initialize or renew a transaction.
+static void LmdbTxnGet(LmdbCtx ctx, enum LmdbOpenMode mode);
+
+// Commit a transaction.
+static void LmdbTxnCommit(LmdbCtx ctx);
+
+// Abort a transaction
+static void LmdbTxnAbort(LmdbCtx ctx);
+
+void LmdbTxnGet(LmdbCtx ctx, enum LmdbOpenMode mode)
+{
+    // Read transactions are reused, if possible
+    if (ctx->txn && mode == LmdbRead)
+    {
+        ctx->err = mdb_txn_renew(ctx->txn);
+        if (ctx->err)
+        {
+            ctx->txn = NULL;
+        }
+    }
+    else if (ctx->txn && mode == LmdbWrite)
+    {
+        LmdbTxnAbort(ctx);
+    }
+
+    if (ctx->txn == NULL)
+    {
+        ctx->err = mdb_txn_begin(ctx->env, NULL, 0, &ctx->txn);
+    }
+
+    if (ctx->err)
+    {
+        ctx->txn = NULL;
+        return;
+    }
+
+    // Given the setup above, and the arguments given, this won't fail.
+    mdb_dbi_open(ctx->txn, NULL, 0, &ctx->dbi);
+}
+
+void LmdbTxnCommit(LmdbCtx ctx)
+{
+    ctx->err = mdb_txn_commit(ctx->txn);
+    ctx->txn = NULL;
+}
+
+void LmdbTxnAbort(LmdbCtx ctx)
+{
+    mdb_txn_abort(ctx->txn);
+    ctx->txn = NULL;
+}
+
+/*
+ * Functions implementing the persistent store interface
+ */
+
+static ps_open_proc   ps_lmdb_open;
+static ps_close_proc  ps_lmdb_close;
+static ps_get_proc    ps_lmdb_get;
+static ps_put_proc    ps_lmdb_put;
+static ps_first_proc  ps_lmdb_first;
+static ps_next_proc   ps_lmdb_next;
+static ps_delete_proc ps_lmdb_delete;
+static ps_free_proc   ps_lmdb_free;
+static ps_geterr_proc ps_lmdb_geterr;
+
+/*
+ * This structure collects all the various pointers
+ * to the functions implementing the lmdb store.
+ */
+
+const PsStore LmdbStore = {
+    "lmdb",
+    NULL,
+    ps_lmdb_open,
+    ps_lmdb_get,
+    ps_lmdb_put,
+    ps_lmdb_first,
+    ps_lmdb_next,
+    ps_lmdb_delete,
+    ps_lmdb_close,
+    ps_lmdb_free,
+    ps_lmdb_geterr,
+    NULL
+};
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterLmdbStore --
+ *
+ *      Register the lmdb store with shared variable implementation.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+void
+Sv_RegisterLmdbStore(void)
+{
+    Sv_RegisterPsStore(&LmdbStore);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_open --
+ *
+ *      Opens the lmdb-based persistent storage.
+ *
+ * Results:
+ *      Opaque handle for LmdbCtx.
+ *
+ * Side effects:
+ *      The lmdb file might be created if not found.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static ClientData
+ps_lmdb_open(
+    const char *path)
+{
+    LmdbCtx ctx;
+
+    char *ext;
+    Tcl_DString toext;
+
+    ctx = ckalloc(sizeof(*ctx));
+    if (ctx == NULL)
+    {
+        return NULL;
+    }
+
+    ctx->env = NULL;
+    ctx->txn = NULL;
+    ctx->cur = NULL;
+    ctx->dbi = 0;
+
+    ctx->err = mdb_env_create(&ctx->env);
+    if (ctx->err)
+    {
+        ckfree(ctx);
+        return NULL;
+    }
+
+    Tcl_DStringInit(&toext);
+    ext = Tcl_UtfToExternalDString(NULL, path, strlen(path), &toext);
+    ctx->err = mdb_env_open(ctx->env, ext, MDB_NOSUBDIR|MDB_NOLOCK, 0666);
+    Tcl_DStringFree(&toext);
+
+    if (ctx->err)
+    {
+        ckfree(ctx);
+        return NULL;
+    }
+
+    return (ClientData)ctx;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_close --
+ *
+ *      Closes the lmdb-based persistent storage.
+ *
+ * Results:
+ *      0 - ok
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int
+ps_lmdb_close(
+    ClientData handle)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    if (ctx->cur)
+    {
+        mdb_cursor_close(ctx->cur);
+    }
+    if (ctx->txn)
+    {
+        LmdbTxnAbort(ctx);
+    }
+
+    mdb_env_close(ctx->env);
+    ckfree(ctx);
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_get --
+ *
+ *      Retrieves data for the key from the lmdb storage.
+ *
+ * Results:
+ *      1 - no such key
+ *      0 - ok
+ *
+ * Side effects:
+ *      Data returned must be copied, then psFree must be called.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int
+ps_lmdb_get(
+     ClientData  handle,
+     const char *keyptr,
+     char  **dataptrptr,
+     size_t     *lenptr)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    MDB_val key, data;
+
+    LmdbTxnGet(ctx, LmdbRead);
+    if (ctx->err)
+    {
+        return 1;
+    }
+
+    key.mv_data = (void *)keyptr;
+    key.mv_size = strlen(keyptr) + 1;
+
+    ctx->err = mdb_get(ctx->txn, ctx->dbi, &key, &data);
+    if (ctx->err)
+    {
+        mdb_txn_reset(ctx->txn);
+        return 1;
+    }
+
+    *dataptrptr = data.mv_data;
+    *lenptr = data.mv_size;
+
+    /*
+     * Transaction is left open at this point, so that the caller can get ahold
+     * of the data and make a copy of it. Afterwards, it will call ps_lmdb_free
+     * to free the data, and we'll catch the chance to reset the transaction
+     * there.
+     */
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_first --
+ *
+ *      Starts the iterator over the lmdb file and returns the first record.
+ *
+ * Results:
+ *      1 - no more records in the iterator
+ *      0 - ok
+ *
+ * Side effects:
+ *      Data returned must be copied, then psFree must be called.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int
+ps_lmdb_first(
+    ClientData  handle,
+    char   **keyptrptr,
+    char  **dataptrptr,
+    size_t     *lenptr)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    MDB_val key, data;
+
+    LmdbTxnGet(ctx, LmdbRead);
+    if (ctx->err)
+    {
+        return 1;
+    }
+
+    ctx->err = mdb_cursor_open(ctx->txn, ctx->dbi, &ctx->cur);
+    if (ctx->err)
+    {
+        return 1;
+    }
+
+    ctx->err = mdb_cursor_get(ctx->cur, &key, &data, MDB_FIRST);
+    if (ctx->err)
+    {
+        mdb_txn_reset(ctx->txn);
+        mdb_cursor_close(ctx->cur);
+        ctx->cur = NULL;
+        return 1;
+    }
+
+    *dataptrptr = data.mv_data;
+    *lenptr = data.mv_size;
+    *keyptrptr = key.mv_data;
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_next --
+ *
+ *      Uses the iterator over the lmdb file and returns the next record.
+ *
+ * Results:
+ *      1 - no more records in the iterator
+ *      0 - ok
+ *
+ * Side effects:
+ *      Data returned must be copied, then psFree must be called.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int ps_lmdb_next(
+    ClientData  handle,
+    char   **keyptrptr,
+    char  **dataptrptr,
+    size_t     *lenptr)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    MDB_val key, data;
+
+    ctx->err = mdb_cursor_get(ctx->cur, &key, &data, MDB_NEXT);
+    if (ctx->err)
+    {
+        mdb_txn_reset(ctx->txn);
+        mdb_cursor_close(ctx->cur);
+        ctx->cur = NULL;
+        return 1;
+    }
+
+    *dataptrptr = data.mv_data;
+    *lenptr = data.mv_size;
+    *keyptrptr = key.mv_data;
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_put --
+ *
+ *      Stores used data bound to a key in lmdb storage.
+ *
+ * Results:
+ *      0 - ok
+ *     -1 - error; use ps_lmdb_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_lmdb_put(
+    ClientData  handle,
+    const char *keyptr,
+    char      *dataptr,
+    size_t         len)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    MDB_val key, data;
+
+    LmdbTxnGet(ctx, LmdbWrite);
+    if (ctx->err)
+    {
+        return -1;
+    }
+
+    key.mv_data = (void*)keyptr;
+    key.mv_size = strlen(keyptr) + 1;
+
+    data.mv_data = dataptr;
+    data.mv_size = len;
+
+    ctx->err = mdb_put(ctx->txn, ctx->dbi, &key, &data, 0);
+    if (ctx->err)
+    {
+        LmdbTxnAbort(ctx);
+    }
+    else
+    {
+        LmdbTxnCommit(ctx);
+    }
+
+    return ctx->err ? -1 : 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_delete --
+ *
+ *      Deletes the key and associated data from the lmdb storage.
+ *
+ * Results:
+ *      0 - ok
+ *     -1 - error; use ps_lmdb_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_lmdb_delete(
+    ClientData  handle,
+    const char *keyptr)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    MDB_val key;
+
+    LmdbTxnGet(ctx, LmdbWrite);
+    if (ctx->err)
+    {
+        return -1;
+    }
+
+    key.mv_data = (void*)keyptr;
+    key.mv_size = strlen(keyptr) + 1;
+
+    ctx->err = mdb_del(ctx->txn, ctx->dbi, &key, NULL);
+    if (ctx->err)
+    {
+        LmdbTxnAbort(ctx);
+    }
+    else
+    {
+        LmdbTxnCommit(ctx);
+    }
+
+    ctx->txn = NULL;
+    return ctx->err ? -1 : 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_free --
+ *
+ *      This function is called to free data returned by the persistent store
+ *      after calls to psFirst, psNext, or psGet. Lmdb doesn't need to free any
+ *      data, as the data returned is owned by lmdb. On the other hand, this
+ *      method is required to reset the read transaction. This is done only
+ *      when iteration is over (ctx->cur == NULL).
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Memory gets reclaimed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static void
+ps_lmdb_free(
+    ClientData handle,
+    void        *data)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    (void)data;
+
+    if (ctx->cur == NULL)
+    {
+        mdb_txn_reset(ctx->txn);
+    }
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_lmdb_geterr --
+ *
+ *      Retrieves the textual representation of the error caused
+ *      by the last lmdb command.
+ *
+ * Results:
+ *      Pointer to the string message.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static const char*
+ps_lmdb_geterr(
+    ClientData handle)
+{
+    LmdbCtx ctx = (LmdbCtx)handle;
+    return mdb_strerror(ctx->err);
+}
+
+#endif  /* HAVE_LMDB */
+
+/* EOF $RCSfile*/
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/pkgs/thread2.8.0/generic/psLmdb.h b/pkgs/thread2.8.0/generic/psLmdb.h
new file mode 100644 (file)
index 0000000..1881c30
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * psLmdb.h --
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _PSLMDB_H_
+#define _PSLMDB_H_
+
+void Sv_RegisterLmdbStore();
+
+#endif /* _PSLMDB_H_ */
+
+/* EOF $RCSfile */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
similarity index 98%
rename from pkgs/thread2.7.3/generic/tclThreadInt.h
rename to pkgs/thread2.8.0/generic/tclThreadInt.h
index 55b8add..00466c9 100644 (file)
@@ -26,9 +26,9 @@
 
 #ifndef MODULE_SCOPE
 #   ifdef __cplusplus
-#      define MODULE_SCOPE extern "C"
+#       define MODULE_SCOPE extern "C"
 #   else
-#      define MODULE_SCOPE extern
+#       define MODULE_SCOPE extern
 #   endif
 #endif
 
similarity index 98%
rename from pkgs/thread2.7.3/generic/tclXkeylist.c
rename to pkgs/thread2.8.0/generic/tclXkeylist.c
index c28578d..6137e69 100644 (file)
@@ -113,11 +113,11 @@ TclX_IsNullObj (objPtr)
     Tcl_Obj *objPtr;
 {
     if (objPtr->typePtr == NULL) {
-       return (objPtr->length == 0);
+        return (objPtr->length == 0);
     } else if (objPtr->typePtr == listType) {
-       int length;
-       Tcl_ListObjLength(NULL, objPtr, &length);
-       return (length == 0);
+        int length;
+        Tcl_ListObjLength(NULL, objPtr, &length);
+        return (length == 0);
     }
     (void)Tcl_GetString(objPtr);
     return (objPtr->length == 0);
@@ -893,9 +893,9 @@ TclX_KeyedListGet (interp, keylPtr, key, valuePtrPtr)
     int findIdx;
 
     if (keylPtr->typePtr != &keyedListType) {
-       if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
-           return TCL_ERROR;
-       }
+        if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
+            return TCL_ERROR;
+        }
     }
     keylIntPtr = keylPtr->internalRep.twoPtrValue.ptr1;
     KEYL_REP_ASSERT (keylIntPtr);
@@ -952,9 +952,9 @@ TclX_KeyedListSet (interp, keylPtr, key, valuePtr)
     Tcl_Obj *newKeylPtr;
 
     if (keylPtr->typePtr != &keyedListType) {
-       if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
-           return TCL_ERROR;
-       }
+        if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
+            return TCL_ERROR;
+        }
     }
     keylIntPtr = keylPtr->internalRep.twoPtrValue.ptr1;
     KEYL_REP_ASSERT (keylIntPtr);
@@ -1052,9 +1052,9 @@ TclX_KeyedListDelete (interp, keylPtr, key)
     int findIdx, status;
 
     if (keylPtr->typePtr != &keyedListType) {
-       if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
-           return TCL_ERROR;
-       }
+        if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
+            return TCL_ERROR;
+        }
     }
     keylIntPtr = keylPtr->internalRep.twoPtrValue.ptr1;
 
@@ -1131,9 +1131,9 @@ TclX_KeyedListGetKeys (interp, keylPtr, key, listObjPtrPtr)
     int idx, findIdx;
 
     if (keylPtr->typePtr != &keyedListType) {
-       if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
-           return TCL_ERROR;
-       }
+        if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
+            return TCL_ERROR;
+        }
     }
     keylIntPtr = keylPtr->internalRep.twoPtrValue.ptr1;
 
similarity index 97%
rename from pkgs/thread2.7.3/generic/threadCmd.c
rename to pkgs/thread2.8.0/generic/threadCmd.c
index 0d04fec..9744230 100644 (file)
@@ -27,7 +27,7 @@
  * files built as part of that shell. Example: basekits.
  */
 #ifndef PACKAGE_VERSION
-#define PACKAGE_VERSION "2.7.3"
+#define PACKAGE_VERSION "2.8.0"
 #endif
 
 /*
@@ -77,7 +77,7 @@
 
 #if defined(TCL_TIP285) && !TCL_MINIMUM_VERSION(8,6)
 # if defined(USE_TCL_STUBS)
-#  define TCL_CANCEL_UNWIND    0x100000
+#  define TCL_CANCEL_UNWIND 0x100000
 #  define Tcl_CancelEval ((int (*)(Tcl_Interp *, Tcl_Obj *, ClientData, int)) \
      ((&(tclStubsPtr->tcl_PkgProvideEx))[580]))
 #  define Tcl_Canceled ((int (*)(Tcl_Interp *, int)) \
@@ -270,9 +270,9 @@ 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
-#define THREAD_SEND_CLBK 1<<3
+#define THREAD_SEND_WAIT (1<<1)
+#define THREAD_SEND_HEAD (1<<2)
+#define THREAD_SEND_CLBK (1<<3)
 
 #ifdef BUILD_thread
 # undef  TCL_STORAGE_CLASS
@@ -435,34 +435,34 @@ ThreadInit(interp)
     Tcl_Interp *interp; /* The current Tcl interpreter */
 {
     if (Tcl_InitStubs(interp, "8.4", 0) == NULL) {
-       if ((sizeof(size_t) != sizeof(int)) ||
-               !Tcl_InitStubs(interp, "8.4-", 0)) {
-           return TCL_ERROR;
-       }
-       Tcl_ResetResult(interp);
+        if ((sizeof(size_t) != sizeof(int)) ||
+                !Tcl_InitStubs(interp, "8.4-", 0)) {
+            return TCL_ERROR;
+        }
+        Tcl_ResetResult(interp);
     }
 
     if (!threadTclVersion) {
 
-       /*
-        * Check whether we are running threaded Tcl.
-        * Get the current core version to decide whether to use
-        * some lately introduced core features or to back-off.
-        */
+        /*
+         * Check whether we are running threaded Tcl.
+         * Get the current core version to decide whether to use
+         * some lately introduced core features or to back-off.
+         */
 
-       int major, minor;
+        int major, minor;
 
-       Tcl_MutexLock(&threadMutex);
-       if (threadMutex == NULL){
-           /* If threadMutex==NULL here, it means that Tcl_MutexLock() is
-            * a dummy function, which is the case in unthreaded Tcl */
-           const char *msg = "Tcl core wasn't compiled for threading";
-           Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
-           return TCL_ERROR;
-       }
-       Tcl_GetVersion(&major, &minor, NULL, NULL);
-       threadTclVersion = 10 * major + minor;
-       Tcl_MutexUnlock(&threadMutex);
+        Tcl_MutexLock(&threadMutex);
+        if (threadMutex == NULL){
+            /* If threadMutex==NULL here, it means that Tcl_MutexLock() is
+             * a dummy function, which is the case in unthreaded Tcl */
+            const char *msg = "Tcl core wasn't compiled for threading";
+            Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
+            return TCL_ERROR;
+        }
+        Tcl_GetVersion(&major, &minor, NULL, NULL);
+        threadTclVersion = 10 * major + minor;
+        Tcl_MutexUnlock(&threadMutex);
     }
 
     TCL_CMD(interp, THREAD_CMD_PREFIX"create",    ThreadCreateObjCmd);
@@ -713,11 +713,11 @@ ThreadReleaseObjCmd(dummy, interp, objc, objv)
     if (objc > 1) {
         if (OPT_CMP(Tcl_GetString(objv[1]), "-wait")) {
             wait = 1;
-           if (objc > 2) {
-               if (ThreadGetId(interp, objv[2], &thrId) != TCL_OK) {
-                   return TCL_ERROR;
-               }
-           }
+            if (objc > 2) {
+                if (ThreadGetId(interp, objv[2], &thrId) != TCL_OK) {
+                    return TCL_ERROR;
+                }
+            }
         } else if (ThreadGetId(interp, objv[1], &thrId) != TCL_OK) {
             return TCL_ERROR;
         }
@@ -785,11 +785,24 @@ ThreadExitObjCmd(dummy, interp, objc, objv)
     int         objc;           /* Number of arguments. */
     Tcl_Obj    *const objv[];   /* Argument objects. */
 {
+    int status = 666;
 
     Init(interp);
+
+    if (objc > 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "?status?");
+        return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+        if (Tcl_GetIntFromObj(interp, objv[1], &status) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+
     ListRemove(NULL);
 
-    Tcl_ExitThread(666);
+    Tcl_ExitThread(status);
 
     return TCL_OK; /* NOT REACHED */
 }
@@ -915,7 +928,7 @@ ThreadNamesObjCmd(dummy, interp, objc, objv)
 static void
 threadSendFree(ClientData ptr)
 {
-       ckfree((char *)ptr);
+    ckfree((char *)ptr);
 }
 
 static int
@@ -1197,14 +1210,14 @@ ThreadErrorProcObjCmd(dummy, interp, objc, objv)
         proc = Tcl_GetString(objv[1]);
         len = objv[1]->length;
         if (len == 0) {
-           errorThreadId = NULL;
+            errorThreadId = NULL;
             errorProcString = NULL;
         } else {
-           errorThreadId = Tcl_GetCurrentThread();
+            errorThreadId = Tcl_GetCurrentThread();
             errorProcString = ckalloc(1+strlen(proc));
             strcpy(errorProcString, proc);
-           Tcl_DeleteThreadExitHandler(ThreadFreeError, NULL);
-           Tcl_CreateThreadExitHandler(ThreadFreeError, NULL);
+            Tcl_DeleteThreadExitHandler(ThreadFreeError, NULL);
+            Tcl_CreateThreadExitHandler(ThreadFreeError, NULL);
         }
     }
     Tcl_MutexUnlock(&threadMutex);
@@ -1218,8 +1231,8 @@ ThreadFreeError(clientData)
 {
     Tcl_MutexLock(&threadMutex);
     if (errorThreadId != Tcl_GetCurrentThread()) {
-       Tcl_MutexUnlock(&threadMutex);
-       return;
+        Tcl_MutexUnlock(&threadMutex);
+        return;
     }
     ckfree(errorProcString);
     errorThreadId = NULL;
@@ -1458,14 +1471,14 @@ ThreadExistsObjCmd(dummy, interp, objc, objv)
  *
  * ThreadConfigureObjCmd --
  *
- *     This procedure is invoked to process the Tcl "thread::configure"
+ *  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.
+ *  A standard Tcl result.
  *
  * Side effects:
- *     None.
+ *  None.
  *----------------------------------------------------------------------
  */
 static int
@@ -1478,7 +1491,7 @@ ThreadConfigureObjCmd(dummy, interp, objc, objv)
     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
+    Tcl_DString ds;             /* DString to hold result of
                                  * calling GetThreadOption. */
 
     if (objc < 2 || (objc % 2 == 1 && objc != 3)) {
@@ -1632,6 +1645,7 @@ ThreadClbkSetVar(interp, clientData)
     const char *var = (const char *)clbkPtr->clientData;
     Tcl_Obj *valObj;
     ThreadEventResult *resultPtr = &clbkPtr->result;
+    int rc = TCL_OK;
 
     /*
      * Get the result of the posted command.
@@ -1639,6 +1653,8 @@ ThreadClbkSetVar(interp, clientData)
      */
 
     valObj = Tcl_NewStringObj(resultPtr->result, -1);
+    Tcl_IncrRefCount(valObj);
+
     if (resultPtr->result != threadEmptyResult) {
         ckfree(resultPtr->result);
     }
@@ -1649,7 +1665,8 @@ ThreadClbkSetVar(interp, clientData)
 
     if (Tcl_SetVar2Ex(interp, var, NULL, valObj,
                       TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) {
-        return TCL_ERROR;
+        rc = TCL_ERROR;
+        goto cleanup;
     }
 
     /*
@@ -1671,7 +1688,9 @@ ThreadClbkSetVar(interp, clientData)
         Tcl_BackgroundError(interp);
     }
 
-    return TCL_OK;
+cleanup:
+    Tcl_DecrRefCount(valObj);
+    return rc;
 }
 \f
 /*
@@ -2451,7 +2470,7 @@ ThreadTransfer(interp, thrId, chan)
         } else {
             Tcl_AppendResult(interp, "for reasons unknown", NULL);
         }
-       ckfree((char *)resultPtr);
+        ckfree((char *)resultPtr);
 
         return TCL_ERROR;
     }
@@ -2684,9 +2703,9 @@ ThreadSend(interp, thrId, send, clbk, flags)
     if (thrId == Tcl_GetCurrentThread()) {
         Tcl_MutexUnlock(&threadMutex);
         if ((flags & THREAD_SEND_WAIT)) {
-           int code = (*send->execProc)(interp, (ClientData)send);
-           ThreadFreeProc((ClientData)send);
-           return code;
+            int code = (*send->execProc)(interp, (ClientData)send);
+            ThreadFreeProc((ClientData)send);
+            return code;
         } else {
             send->interp = interp;
             Tcl_Preserve((ClientData)send->interp);
@@ -2755,12 +2774,12 @@ ThreadSend(interp, thrId, send, clbk, flags)
          * Might potentially spend some time here, until the
          * worker thread cleans up its queue a little bit.
          */
-       if ((flags & THREAD_SEND_CLBK) == 0) {
+        if ((flags & THREAD_SEND_CLBK) == 0) {
             while (tsdPtr->maxEventsCount &&
                    tsdPtr->eventsPending > tsdPtr->maxEventsCount) {
                 Tcl_ConditionWait(&tsdPtr->doOneEvent, &threadMutex, NULL);
             }
-       }
+        }
         Tcl_MutexUnlock(&threadMutex);
         return TCL_OK;
     }
@@ -2914,7 +2933,7 @@ ThreadWait(Tcl_Interp *interp)
 
         errorInfo = Tcl_GetVar2(tsdPtr->interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
         if (errorInfo == NULL) {
-               errorInfo = Tcl_GetString(Tcl_GetObjResult(tsdPtr->interp));
+            errorInfo = Tcl_GetString(Tcl_GetObjResult(tsdPtr->interp));
         }
 
         ThreadGetHandle(Tcl_GetCurrentThread(), buf);
similarity index 97%
rename from pkgs/thread2.7.3/generic/threadNs.c
rename to pkgs/thread2.8.0/generic/threadNs.c
index fa4184a..45b6b09 100644 (file)
@@ -40,7 +40,7 @@ NsThread_Init (Tcl_Interp *interp, void *cd)
 
     if (ret != TCL_OK) {
         Ns_Log(Warning, "can't load module %s: %s", md->modname,
-                       Tcl_GetString(Tcl_GetObjResult(interp)));
+                Tcl_GetString(Tcl_GetObjResult(interp)));
         return TCL_ERROR;
     }
     Tcl_SetAssocData(interp, "thread:nsd", NULL, (ClientData)md);
similarity index 98%
rename from pkgs/thread2.7.3/generic/threadSpCmd.c
rename to pkgs/thread2.8.0/generic/threadSpCmd.c
index 03df92a..dbb849e 100644 (file)
@@ -96,7 +96,7 @@ static int        initOnce;    /* Flag for initializing tables below */
 static Tcl_Mutex  initMutex;   /* Controls initialization of primitives */
 static SpBucket  muxBuckets[NUMSPBUCKETS];  /* Maps mutex names/handles */
 static SpBucket  varBuckets[NUMSPBUCKETS];  /* Maps condition variable
-                                            * names/handles */
+                                             * names/handles */
 
 /*
  * Functions implementing Tcl commands
@@ -1243,7 +1243,7 @@ SpMutexFinalize(SpMutex *mutexPtr)
 static int
 SpCondvWait(SpCondv *condvPtr, SpMutex *mutexPtr, int msec)
 {
-       Sp_AnyMutex **lock = &mutexPtr->lock;
+    Sp_AnyMutex **lock = &mutexPtr->lock;
     Sp_ExclusiveMutex_ *emPtr = *(Sp_ExclusiveMutex_**)lock;
     Tcl_Time waitTime, *wt = NULL;
     Tcl_ThreadId threadId = Tcl_GetCurrentThread();
@@ -1544,27 +1544,27 @@ Sp_RecursiveMutexLock(Sp_RecursiveMutex *muxPtr)
          * We are already holding the mutex
          * so just count one more lock.
          */
-       rmPtr->lockcount++;
+        rmPtr->lockcount++;
     } else {
-       if (rmPtr->owner == (Tcl_ThreadId)0) {
+        if (rmPtr->owner == (Tcl_ThreadId)0) {
             /*
              * Nobody holds the mutex, we do now.
              */
-               rmPtr->owner = thisThread;
-               rmPtr->lockcount = 1;
-       } else {
+            rmPtr->owner = thisThread;
+            rmPtr->lockcount = 1;
+        } else {
             /*
              * Somebody else holds the mutex; wait.
              */
-               while (1) {
+            while (1) {
                 Tcl_ConditionWait(&rmPtr->cond, &rmPtr->lock, NULL);
-                       if (rmPtr->owner == (Tcl_ThreadId)0) {
-                               rmPtr->owner = thisThread;
-                               rmPtr->lockcount = 1;
-                               break;
-                       }
-               }
-       }
+                if (rmPtr->owner == (Tcl_ThreadId)0) {
+                    rmPtr->owner = thisThread;
+                    rmPtr->lockcount = 1;
+                    break;
+                }
+            }
+        }
     }
 
     Tcl_MutexUnlock(&rmPtr->lock);
similarity index 98%
rename from pkgs/thread2.7.3/generic/threadSpCmd.h
rename to pkgs/thread2.8.0/generic/threadSpCmd.h
index e2c7c07..70fcc4f 100644 (file)
@@ -79,7 +79,7 @@ typedef struct Sp_ReadWriteMutex_ {
     Tcl_Mutex lock;             /* Regular mutex */
     Tcl_ThreadId owner;         /* Current lock owner thread */
     /* --- */
-    unsigned int numrd;                /* # of readers waiting for lock */
+    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 */
similarity index 94%
rename from pkgs/thread2.7.3/generic/threadSvCmd.c
rename to pkgs/thread2.8.0/generic/threadSvCmd.c
index b8d90c0..02857c0 100644 (file)
@@ -19,6 +19,9 @@
 #include "threadSvListCmd.h"    /* Shared variants of list commands */
 #include "threadSvKeylistCmd.h" /* Shared variants of list commands */
 #include "psGdbm.h"             /* The gdbm persistent store implementation */
+#include "psLmdb.h"             /* The lmdb persistent store implementation */
+
+#define SV_FINALIZE
 
 /*
  * Number of buckets to spread shared arrays into. Each bucket is
@@ -58,6 +61,11 @@ static char *Sv_tclEmptyStringRep = NULL;
  * Global variables used within this file.
  */
 
+#ifdef SV_FINALIZE
+static size_t     nofThreads;      /* Number of initialized threads */
+static Tcl_Mutex  nofThreadsMutex; /* Protects the nofThreads variable */
+#endif /* SV_FINALIZE */
+
 static Bucket*    buckets;      /* Array of buckets. */
 static Tcl_Mutex  bucketsMutex; /* Protects the array of buckets */
 
@@ -83,6 +91,7 @@ static Tcl_ObjCmdProc SvGetObjCmd;
 static Tcl_ObjCmdProc SvArrayObjCmd;
 static Tcl_ObjCmdProc SvUnsetObjCmd;
 static Tcl_ObjCmdProc SvNamesObjCmd;
+static Tcl_ObjCmdProc SvHandlersObjCmd;
 
 /*
  * New commands added to
@@ -112,7 +121,6 @@ static int DeleteArray(Array*);
 static void SvAllocateContainers(Bucket*);
 static void SvRegisterStdCommands(void);
 
-#define SV_FINALIZE
 #ifdef SV_FINALIZE
 static void SvFinalizeContainers(Bucket*);
 static void SvFinalize(ClientData);
@@ -512,7 +520,7 @@ AcquireContainer(
             size_t len = 0;
             if (psPtr->psGet(psPtr->psHandle, key, &val, &len) == 0) {
                 tclObj = Tcl_NewStringObj(val, len);
-                psPtr->psFree(val);
+                psPtr->psFree(psPtr->psHandle, val);
             }
         }
         if (!(flags & FLAGS_CREATEVAR) && tclObj == NULL) {
@@ -1318,7 +1326,9 @@ SvArrayObjCmd(
          */
 
         PsStore *psPtr;
+        Tcl_HashEntry *hPtr;
         size_t len;
+        int new;
         char *psurl, *key = NULL, *val = NULL;
 
         if (objc < 4) {
@@ -1345,7 +1355,7 @@ SvArrayObjCmd(
         }
         if (arrayPtr) {
             Tcl_HashSearch search;
-            Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&arrayPtr->vars,&search);
+            hPtr = Tcl_FirstHashEntry(&arrayPtr->vars,&search);
             arrayPtr->psPtr = psPtr;
             arrayPtr->bindAddr = strcpy(ckalloc(len+1), psurl);
             while (hPtr) {
@@ -1363,8 +1373,10 @@ SvArrayObjCmd(
         }
         if (!psPtr->psFirst(psPtr->psHandle, &key, &val, &len)) {
             do {
-                psPtr->psFree(val); /* What a waste! */
-                AcquireContainer(arrayPtr, key, FLAGS_CREATEVAR);
+                Tcl_Obj * tclObj = Tcl_NewStringObj(val, len);
+                hPtr = Tcl_CreateHashEntry(&arrayPtr->vars, key, &new);
+                Tcl_SetHashValue(hPtr, CreateContainer(arrayPtr, hPtr, tclObj));
+                psPtr->psFree(psPtr->psHandle, val);
             } while (!psPtr->psNext(psPtr->psHandle, &key, &val, &len));
         }
 
@@ -2015,8 +2027,8 @@ SvLockObjCmd(
      */
 
     if (objc < 3) {
-       Tcl_WrongNumArgs(interp, 1, objv, "array arg ?arg...?");
-       return TCL_ERROR;
+        Tcl_WrongNumArgs(interp, 1, objv, "array arg ?arg...?");
+        return TCL_ERROR;
     }
 
     arrayPtr  = LockArray(interp, Tcl_GetString(objv[1]), FLAGS_CREATEARRAY);
@@ -2055,6 +2067,53 @@ SvLockObjCmd(
 
     return ret;
 }
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvHandlersObjCmd --
+ *
+ *    This procedure is invoked to process "tsv::handlers" Tcl command.
+ *    See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int
+SvHandlersObjCmd(
+             ClientData arg,                     /* Not used. */
+             Tcl_Interp *interp,                 /* Current interpreter. */
+             int objc,                           /* Number of arguments. */
+             Tcl_Obj *const objv[])              /* Argument objects. */
+{
+    PsStore *tmpPtr = NULL;
+
+    /*
+     * Syntax:
+     *
+     *     tsv::handlers
+     */
+
+    if (objc != 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    Tcl_ResetResult(interp);
+    Tcl_MutexLock(&svMutex);
+    for (tmpPtr = psStore; tmpPtr; tmpPtr = tmpPtr->nextPtr) {
+        Tcl_AppendElement(interp, tmpPtr->type);
+    }
+    Tcl_MutexUnlock(&svMutex);
+
+    return TCL_OK;
+}
+
 \f
 /*
  *-----------------------------------------------------------------------------
@@ -2080,19 +2139,20 @@ SvRegisterStdCommands(void)
     if (initialized == 0) {
         Tcl_MutexLock(&initMutex);
         if (initialized == 0) {
-            Sv_RegisterCommand("var",    SvObjObjCmd,    NULL, 1);
-            Sv_RegisterCommand("object", SvObjObjCmd,    NULL, 1);
-            Sv_RegisterCommand("set",    SvSetObjCmd,    NULL, 0);
-            Sv_RegisterCommand("unset",  SvUnsetObjCmd,  NULL, 0);
-            Sv_RegisterCommand("get",    SvGetObjCmd,    NULL, 0);
-            Sv_RegisterCommand("incr",   SvIncrObjCmd,   NULL, 0);
-            Sv_RegisterCommand("exists", SvExistsObjCmd, NULL, 0);
-            Sv_RegisterCommand("append", SvAppendObjCmd, NULL, 0);
-            Sv_RegisterCommand("array",  SvArrayObjCmd,  NULL, 0);
-            Sv_RegisterCommand("names",  SvNamesObjCmd,  NULL, 0);
-            Sv_RegisterCommand("pop",    SvPopObjCmd,    NULL, 0);
-            Sv_RegisterCommand("move",   SvMoveObjCmd,   NULL, 0);
-            Sv_RegisterCommand("lock",   SvLockObjCmd,   NULL, 0);
+            Sv_RegisterCommand("var",      SvObjObjCmd,      NULL, 1);
+            Sv_RegisterCommand("object",   SvObjObjCmd,      NULL, 1);
+            Sv_RegisterCommand("set",      SvSetObjCmd,      NULL, 0);
+            Sv_RegisterCommand("unset",    SvUnsetObjCmd,    NULL, 0);
+            Sv_RegisterCommand("get",      SvGetObjCmd,      NULL, 0);
+            Sv_RegisterCommand("incr",     SvIncrObjCmd,     NULL, 0);
+            Sv_RegisterCommand("exists",   SvExistsObjCmd,   NULL, 0);
+            Sv_RegisterCommand("append",   SvAppendObjCmd,   NULL, 0);
+            Sv_RegisterCommand("array",    SvArrayObjCmd,    NULL, 0);
+            Sv_RegisterCommand("names",    SvNamesObjCmd,    NULL, 0);
+            Sv_RegisterCommand("pop",      SvPopObjCmd,      NULL, 0);
+            Sv_RegisterCommand("move",     SvMoveObjCmd,     NULL, 0);
+            Sv_RegisterCommand("lock",     SvLockObjCmd,     NULL, 0);
+            Sv_RegisterCommand("handlers", SvHandlersObjCmd, NULL, 0);
             initialized = 1;
         }
         Tcl_MutexUnlock(&initMutex);
@@ -2125,6 +2185,20 @@ Sv_Init (interp)
     const Tcl_UniChar no[3] = {'n', 'o', 0} ;
     Tcl_Obj *obj;
 
+#ifdef SV_FINALIZE
+    /*
+     * Create exit handler for this thread
+     */
+    Tcl_CreateThreadExitHandler(SvFinalize, NULL);
+
+    /*
+     * Increment number of threads
+     */
+    Tcl_MutexLock(&nofThreadsMutex);
+    ++nofThreads;
+    Tcl_MutexUnlock(&nofThreadsMutex);
+#endif /* SV_FINALIZE */
+
     /*
      * Add keyed-list datatype
      */
@@ -2184,7 +2258,6 @@ Sv_Init (interp)
         Tcl_MutexLock(&bucketsMutex);
         if (buckets == NULL) {
             buckets = (Bucket *)ckalloc(sizeof(Bucket) * NUMBUCKETS);
-           Tcl_CreateExitHandler(SvFinalize, NULL);
 
             for (i = 0; i < NUMBUCKETS; ++i) {
                 bucketPtr = &buckets[i];
@@ -2204,12 +2277,15 @@ Sv_Init (interp)
                 Tcl_DecrRefCount(dummy);
             }
 
-#ifdef HAVE_GDBM
             /*
              * Register persistent store handlers
              */
+#ifdef HAVE_GDBM
             Sv_RegisterGdbmStore();
 #endif
+#ifdef HAVE_LMDB
+            Sv_RegisterLmdbStore();
+#endif
         }
         Tcl_MutexUnlock(&bucketsMutex);
     }
@@ -2252,6 +2328,18 @@ SvFinalize (ClientData clientData)
     Tcl_HashSearch search;
 
     /*
+     * Decrement number of threads. Proceed only if I was the last one. The
+     * mutex is unlocked at the end of this function, so new threads that might
+     * want to register in the meanwhile will find a clean environment when
+     * they eventually succeed acquiring nofThreadsMutex.
+     */
+    Tcl_MutexLock(&nofThreadsMutex);
+    if (nofThreads > 1)
+    {
+        goto done;
+    }
+
+    /*
      * Reclaim memory for shared arrays
      */
 
@@ -2311,6 +2399,10 @@ SvFinalize (ClientData clientData)
     }
 
     Tcl_MutexUnlock(&svMutex);
+
+done:
+    --nofThreads;
+    Tcl_MutexUnlock(&nofThreadsMutex);
 }
 #endif /* SV_FINALIZE */
 
similarity index 99%
rename from pkgs/thread2.7.3/generic/threadSvCmd.h
rename to pkgs/thread2.8.0/generic/threadSvCmd.h
index 85c6680..228d134 100644 (file)
@@ -89,7 +89,7 @@ typedef int (ps_first_proc) (ClientData, char**, char**, size_t*);
 typedef int (ps_next_proc)  (ClientData, char**, char**, size_t*);
 typedef int (ps_delete_proc)(ClientData, const char*);
 typedef int (ps_close_proc) (ClientData);
-typedef void(ps_free_proc)  (void*);
+typedef void(ps_free_proc)  (ClientData, void*);
 
 typedef const char* (ps_geterr_proc)(ClientData);
 
similarity index 99%
rename from pkgs/thread2.7.3/lib/ttrace.tcl
rename to pkgs/thread2.8.0/lib/ttrace.tcl
index 4eb6b77..e952f78 100644 (file)
@@ -2,7 +2,7 @@
 # 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.
 # ----------------------------------------------------------------------------
@@ -73,7 +73,7 @@ namespace eval ttrace {
     }
 
     # Keep in sync with the Thread package
-    package provide Ttrace 2.7.3
+    package provide Ttrace 2.8.0
 
     # Package variables
     variable resolvers ""     ; # List of registered resolvers
@@ -187,7 +187,7 @@ namespace eval ttrace {
     }
 
     proc update {{from -1}} {
-        if {$from == -1} { 
+        if {$from == -1} {
             variable epoch [_set ttrace lastepoch]
         } else {
             if {[lsearch [_set ttrace epochlist] $from] == -1} {
@@ -196,7 +196,7 @@ namespace eval ttrace {
             variable epoch $from
         }
         uplevel [getscript]
-    } 
+    }
 
     proc getscript {} {
         variable preloads
@@ -238,7 +238,7 @@ namespace eval ttrace {
             return $cmd
         }
     }
-    
+
     proc atdisable {cmd arglist body} {
         variable disables
         if {[lsearch $disables $cmd] == -1} {
@@ -248,7 +248,7 @@ namespace eval ttrace {
             return $cmd
         }
     }
-     
+
     proc addtrace {cmd arglist body} {
         variable tracers
         if {[lsearch $tracers $cmd] == -1} {
@@ -396,7 +396,7 @@ namespace eval ttrace {
     }
 
     proc _dropepoch {epoch threads} {
-        set self [_getthread] 
+        set self [_getthread]
         foreach tid [_set ttrace $epoch] {
             if {$tid != $self && [lsearch $threads $tid] >= 0} {
                 lappend alive $tid
@@ -637,7 +637,7 @@ eval {
             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 
+                append res " [list [set $entry]]" \n
             } else {
                 append res \n
             }
@@ -870,7 +870,7 @@ eval {
     }
 
     ttrace::atdisable XOTclDisabler {args} {
-        if {   [info commands ::xotcl::Class] == "" 
+        if {   [info commands ::xotcl::Class] == ""
             || [info commands ::xotcl::_creator] == ""} {
             return
         }
@@ -914,7 +914,7 @@ eval {
     #
     # Register callback to be called on cleanup. This will trash lazily loaded
     # procs which have changed since.
-    # 
+    #
 
     ttrace::addcleanup {
         variable resolveproc
similarity index 98%
rename from pkgs/thread2.7.3/license.terms
rename to pkgs/thread2.8.0/license.terms
index 9df3e60..f87ed92 100644 (file)
@@ -28,7 +28,7 @@ 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 
+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
@@ -36,4 +36,4 @@ 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. 
+terms specified in this license.
similarity index 60%
rename from pkgs/thread2.7.3/tcl/README
rename to pkgs/thread2.8.0/tcl/README
index fe1b751..15e1edd 100644 (file)
@@ -6,27 +6,27 @@ 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 
+             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 
+             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 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 
+   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 
+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
similarity index 95%
rename from pkgs/thread2.7.3/tcl/cmdsrv/cmdsrv.tcl
rename to pkgs/thread2.8.0/tcl/cmdsrv/cmdsrv.tcl
index 8ce7cef..01ec508 100644 (file)
@@ -3,10 +3,10 @@
 #
 # 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)
@@ -18,7 +18,7 @@
 #    % cmdsrv::create 5000 -idletime 60
 #    % vwait forever
 #
-#    Starts the server on the port 5000, sets idle timer to 1 minute. 
+#    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.
@@ -66,7 +66,7 @@ proc cmdsrv::create {port args} {
         -idletime 300000
         -initcmd  {source cmdsrv.tcl}
     }
-    
+
     #
     # Override with user-supplied data
     #
@@ -86,7 +86,7 @@ proc cmdsrv::create {port args} {
     # 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
@@ -133,23 +133,23 @@ proc cmdsrv::_Accept {s ipaddr port} {
 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
 
@@ -168,9 +168,9 @@ proc cmdsrv::Accept {s ipaddr port} {
 #
 # cmdsrv::Read --
 #
-#      Event loop procedure to read data from socket and collect the 
+#      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. 
+#   it executes the command are prints the result back.
 #
 # Arguments:
 #   s      incoming socket
@@ -201,7 +201,7 @@ proc cmdsrv::Read {s} {
         }
         return [StartIdleTimer $s]
     }
-    
+
     #
     # Construct command line to eval
     #
@@ -233,7 +233,7 @@ proc cmdsrv::Read {s} {
 # cmdsrv::SockDone --
 #
 #      Tears down the thread and closes the socket if the remote peer has
-#   closed his side of the comm channel. 
+#   closed his side of the comm channel.
 #
 # Arguments:
 #   s      incoming socket
@@ -254,7 +254,7 @@ proc cmdsrv::SockDone {s} {
 #
 # cmdsrv::StopIdleTimer --
 #
-#      Cancel the connection idle timer. 
+#      Cancel the connection idle timer.
 #
 # Arguments:
 #   s      incoming socket
@@ -279,7 +279,7 @@ proc cmdsrv::StopIdleTimer {s} {
 #
 # cmdsrv::StartIdleTimer --
 #
-#      Initiates the connection idle timer. 
+#      Initiates the connection idle timer.
 #
 # Arguments:
 #   s      incoming socket
similarity index 99%
rename from pkgs/thread2.7.3/tcl/phttpd/phttpd.tcl
rename to pkgs/thread2.8.0/tcl/phttpd/phttpd.tcl
index 5a01a75..8f0c42d 100644 (file)
@@ -9,7 +9,7 @@
 #
 # Usage:
 #    phttpd::create port
-# 
+#
 #    port         Tcp port where the server listens
 #
 # Example:
@@ -20,7 +20,7 @@
 #    % vwait forever
 #
 #    Starts the server on the port 5000. Also, look at the Httpd array
-#    definition in the "phttpd" namespace declaration to find out 
+#    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
@@ -139,7 +139,7 @@ proc phttpd::create {port args} {
     # 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
@@ -201,7 +201,7 @@ proc phttpd::Accept {sock ipaddr port} {
 
     #
     # Send the work ticket to threadpool.
-    # 
+    #
 
     tpool::post -detached $Httpd(tpid) [list [namespace current]::Ticket $sock]
 }
@@ -222,15 +222,15 @@ proc phttpd::Accept {sock ipaddr port} {
 #
 
 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
 }
 
@@ -272,9 +272,9 @@ proc phttpd::Read {sock} {
                 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" {
@@ -333,7 +333,7 @@ proc phttpd::Done {} {
     variable data
 
     close $data(sock)
-    
+
     if {[info exists data]} {
         unset data
     }
@@ -430,7 +430,7 @@ proc phttpd::ContentType {path} {
 
     set type "text/plain"
     catch {set type $MimeTypes([file extension $path])}
-    
+
     return $type
 }
 \f
@@ -617,7 +617,7 @@ proc phttpd::CgiMap {data} {
 #
 
 proc phttpd::QueryMap {query} {
-    
+
     set res [list]
 
     regsub -all {[&=]} $query { }    query
similarity index 98%
rename from pkgs/thread2.7.3/tcl/phttpd/uhttpd.tcl
rename to pkgs/thread2.8.0/tcl/phttpd/uhttpd.tcl
index 0680523..b44338a 100644 (file)
@@ -9,7 +9,7 @@
 #
 # Usage:
 #    phttpd::create port
-# 
+#
 #    port         Tcp port where the server listens
 #
 # Example:
@@ -20,7 +20,7 @@
 #    % vwait forever
 #
 #    Starts the server on the port 5000. Also, look at the Httpd array
-#    definition in the "uhttpd" namespace declaration to find out 
+#    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
@@ -74,7 +74,7 @@ proc uhttpd::create {port args} {
 
     # @c Start the server by listening for connections on the desired port.
 
-    variable Httpd 
+    variable Httpd
     set arglen [llength $args]
 
     if {$arglen} {
@@ -97,21 +97,21 @@ proc uhttpd::create {port args} {
 }
 
 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" 
+        puts $s "Content-Length: $length"
     } else {
         puts $s "Content-Length: [string length $data]"
     }
 
     puts $s ""
-    puts $s $data 
+    puts $s $data
 }
-       
+
 proc uhttpd::Accept {newsock ipaddr port} {
 
     # @c Accept a new connection from the client.
@@ -258,7 +258,7 @@ proc uhttpd::ContentType {path} {
 
     set type "text/plain"
     catch {set type $MimeTypes([file extension $path])}
-    
+
     return $type
 }
 
@@ -306,7 +306,7 @@ proc uhttpd::Date {{seconds 0}} {
 }
 
 proc uhttpd::Log {reason format args} {
-    
+
     # @c Log an httpd transaction.
 
     set messg [eval format [list $format] $args]
@@ -363,7 +363,7 @@ proc uhttpd::CgiMap {data} {
 proc uhttpd::QueryMap {query} {
 
     # @c Decode url-encoded query into key/value pairs
-    
+
     set res [list]
 
     regsub -all {[&=]} $query { }    query
similarity index 97%
rename from pkgs/thread2.7.3/tcl/tpool/tpool.tcl
rename to pkgs/thread2.8.0/tcl/tpool/tpool.tcl
index c33c957..021e231 100644 (file)
@@ -2,20 +2,20 @@
 # tpool.tcl --
 #
 # Tcl implementation of a threadpool paradigm in pure Tcl using
-# the Tcl threading extension 2.5 (or higher). 
+# 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 
+# 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.
 #
@@ -66,7 +66,7 @@ namespace eval tpool {
 #   Might create many new threads if "-minworkers" option is > 0.
 #
 # Results:
-#   The id of the newly created thread pool. This id must be used 
+#   The id of the newly created thread pool. This id must be used
 #   in all other tpool::* commands.
 #
 
@@ -167,7 +167,7 @@ proc tpool::names {} {
 #   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 
+#   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.
 #
@@ -176,7 +176,7 @@ proc tpool::names {} {
 #          tpool::post ?-detached? tpid script
 #
 #          -detached  flag to turn the async operation (ignore result)
-#          tpid       the id of the thread pool 
+#          tpid       the id of the thread pool
 #          script     script to pass to the worker thread for execution
 #
 # Side Effects:
@@ -194,7 +194,7 @@ 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\""
@@ -209,14 +209,14 @@ proc tpool::post {args} {
         }
         set detached 1
         set tpid [lindex $args 1]
-        set cmd  [lindex $args 2]            
+        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 
+    # a complex issue, since we must honour the limits about number
     # of allowed worker threads imposed to us by the caller.
     #
 
@@ -463,11 +463,11 @@ 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 
+            # workers, adjust the number of workers and release
             # this thread, which may exit eventually.
             #
 
@@ -513,7 +513,7 @@ proc tpool::Run {tpid jid cmd} {
     if {$afterevent != ""} {
         after cancel $afterevent
     }
-    
+
     #
     # Evaluate passed command and build the result list.
     #
@@ -529,7 +529,7 @@ proc tpool::Run {tpid jid cmd} {
     # 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 {
@@ -543,7 +543,7 @@ proc tpool::Run {tpid jid cmd} {
     }
 
     #
-    # Release the thread. If this turns out to be 
+    # 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.
     #
diff --git a/pkgs/thread2.8.0/tests/French.txt b/pkgs/thread2.8.0/tests/French.txt
new file mode 100644 (file)
index 0000000..ccbbab7
--- /dev/null
@@ -0,0 +1,3257 @@
+###########################################################################
+#Copyright 1999 The Internet Dictionary Project/Tyler Chambers
+#http://www.june29.com/IDP/
+#This file is free to use and modify.  Thank you for using the IDP.
+#
+#Approximately 1340 entries.  9/21/97
+#Approximately 1884 entries.  1/7/98
+#Appriximately 2160 entries.  3/8/98
+#Approximately 3040 entries.  8/18/98
+#Approximately 3250 entries. 2/19/99
+###########################################################################
+a      un(e): ~ book = un livre. 2.(instead of number one) ~ year ago; il y a un an[Article]
+a      un, une[Pronoun]
+aardvark       orycte/rope[Noun]
+aardvark       adverbe[Adverb]
+aardvarks      tamanoirs
+aback  etre deconcerte[Verb]
+aback  to be taken ~ : etre deconcerte,interdit[Adverb]
+aback  to be taken ~ :etre stupefait(e)[Adjective]
+abacterial     non-bacte/rien[Adjective]
+abacus abaque,boulier (compteur)[Noun]
+abacus abaque[Noun]
+abacus boulier,compteur[Noun]
+abacuses       abaques, bouliers
+abacuses       abaques[Noun]
+abacuses       bouliers, compteurs[Noun]
+abaft  sur l'arrie\re, vers l'arrie\re[Adverb]
+abalone        ormeau[Noun]
+abalones       ormeaux[Noun]
+abandon        abandon, laisser-aller[Noun]
+abandon        abandonner[Verb]
+abandoned      abandonne/[Adjective]
+abandoned      abandonnes[Adjective]
+abandoned      de/vergonde/[Adjective]
+abandonee      abandoned, forsaken[Adjective]
+abandoner      abandoneur[Adjective]
+abandoning     abandonnant[Verb]
+abandonment    abandon[Noun]
+abandonment    abandonnement[Noun]
+abandonments   abandons[Noun]
+abandons       abandonnes[Verb]
+abase  abaisser, humilier[Verb]
+abased humilie/
+abasement      abaissement, humiliation[Noun]
+abasements     abaissement[Noun]
+abases mortifie, humilie, rabaisse[Verb]
+abash  confondre, de/concerter[Verb]
+abashed        confus(e), embarrasse(e)[Adjective]
+abashed        deconcerte, confus, gene[Adjective]
+abasing        humiliant[Adjective]
+abate  diminuer[Verb]
+abate  s'apaiser, se calmer[Verb]
+abated a diminue/[Verb]
+abatement      diminution[Noun]
+abatement      la suppression[Noun]
+abatements     coupures
+abates se calme, s'apaise[Verb]
+abating        faiblant[Adjective]
+abating        faiblant[Adjective]
+abattoir       abattoir[Noun]
+abbe   abbe/[Noun]
+abberations    aberrations[Noun]
+abbey  abbaye (f)[Noun]
+abbey  une abbaye[Noun]
+abbeys abbayes[Noun]
+abbot  abbe ( d'un monastere)[Noun]
+abbot  abbe/
+abbot  abbe/[Noun]
+abbot  pere superieur[Noun]
+abbot  abbe/[Noun]
+abbots abbe/s[Noun]
+abbreviate     abbre/ger[Verb]
+abbreviate     abre/ger[Verb]
+abbreviated    abbre/gé[Verb]
+abbreviates    s'abre\ge[Verb]
+abbreviating   abre/geant[Verb]
+abbreviation   abbre/viation[Noun]
+abbreviation   abre/viation[Noun]
+abbreviation   abreviation (f)[Noun]
+abbreviations  abbre/viations[Noun]
+abbreviations  abre/viations[Noun]
+abbreviator    abre/viateur[Noun]
+abdicable      abdiquable[Adjective]
+abdicate       abdiquer[Verb]
+abdicate       renoncer[Verb]
+abdicated      abdique/[Adjective]
+abdication     abdication[Verb]
+abdicator      abdicateur[Adjective]
+abdomen        abdomen (m)[Noun]
+abdomen        abdomen[Noun]
+abdomens       abdomens[Noun]
+abdominal      abdominal[Adjective]
+abdominally    abdominalement[Adverb]
+abduct enlever[Verb]
+abducted       enlevé[Verb]
+abducting      enlevant[Verb]
+abduction      enlèvement[Noun]
+abductions     enlèvements[Noun]
+abductor       adducteur[Adjective]
+abductors      adducteur[Adjective]
+abducts        detourner[Verb]
+abeam  par le travers[Adverb]
+abecedarian    abécédaire[Noun]
+abed   au lit[Noun]
+aberrance      aberration (f)[Noun]
+aberrant       aberrant, egare[Adjective]
+aberrantly     de fac,on aberrante[Adverb]
+aberration     aberration[Noun]
+aberration     anomalie (f)[Noun]
+aberrations    erreurs
+abet   encourager (au crime)[Verb]
+abetment       encouragement[Noun]
+abets  secourirs
+abetted        encouragea, soutient[Verb]
+abetter        complice[Noun]
+abetting       provoquant[Adjective]
+abettor        aide, complice[Noun]
+abeyance       in ~ (law): en desuetude; (matter) en suspens[Noun]
+abeyant        en attente[Adjective]
+abhor  avoir horreur de[Verb]
+abhorred       abhorrait or abhorre/, de/testait or de/teste/[Verb]
+abhorrence     aversion extreme, horreur[Noun]
+abhorrent      odieux
+abhorrently    de fac,on odieuse[Adverb]
+abhorring      abhorrant[Adjective]
+abhors abhorrer[Verb]
+abide  i can't ~ it/him : je ne peut pas le souffrir &lt;or&gt; supporter; to ~ by : observer, respecter[Verb]
+abided souffri[Adjective]
+abides tole\re, demeure, subsiste[Verb]
+abiding        constant, e/ternel[Adjective]
+abilities      talents[Noun]
+ability        compe/tence
+ability        competence (f); capacite (f); (skill) talent (m)[Noun]
+abiotic        abiotique[Adjective]
+abject (poverty) sordid; (apology) plat(e)[Adjective]
+abjection      abjection(f)[Noun]
+abjectly       avec servilite/[Adjective]
+abjuration     renoncement, apostasie (rel)[Noun]
+abjure abjurer[Verb]
+abjurer        personne qui abjure
+ablation       ablation
+ablative       ablatif[Adjective]
+ablaze en feu
+ablaze en feu, en flammes[Adjective]
+able   compe/tent(e)
+able   competent(e); to be ~ to do sth : pouvoir faire qch, etre capable de faire qch[Adjective]
+able   capable -to be able to e^tre capable de , pouvoir
+able   to be ~: pouvoir[Verb]
+abler  plus compétent(e)[Adjective]
+ablest le plus compe/tent[Adjective]
+abloom en fleur
+ablution       ablution[Noun]
+ablutions      ablutions[Noun]
+ably   de fac,on compe/tente, habilement[Adjective]
+abnegate       Renouncer Ã [Verb]
+abnegates      renie, re/pudie, rejette[Verb]
+abnegation     abne/gation[Noun]
+abnormal       abnormal(e)[Adjective]
+abnormal       anormal(e)[Adjective]
+abnormal       anormal
+abnormalities  anomalies, difformite/s[Noun]
+abnormality    anomalie, malformation[Noun]
+abnormally     anormalement[Adverb]
+aboard a\ bord
+abode  of no fixed ~ :sans domicile fixe[Noun]
+abodes demeures, domiciles[Noun]
+aboil  en train de bouillir[Verb]
+abolish        abolir[Verb]
+abolish        abroger, supprimer[Verb]
+abolishable    qui peut e^tre aboli
+abolished      aboli(es)[Verb]
+abolisher      suppresseur[Adjective]
+abolishes      abolit, abroge, supprime
+abolishment    suppression, abolition, abrogation[Noun]
+abolition      abolition
+abolition      suppression[Noun]
+abolitionism   abolitionnisme[Noun]
+abolitionist   abolitionniste[Adjective]
+abolitionists  abolitionnistes, antiesclavagistes (hist)[Noun]
+abominable     abominable[Adjective]
+abominably     abominablement, odieusement[Adverb]
+abominate      abhorrer, exe/crer, abominer[Verb]
+abomination    abomination[Noun]
+abominations   abominations[Noun]
+aboriginal     aborige\ne[Noun]
+aboriginally   aboriginalement[Adverb]
+aborigine      aborigene m/f[Noun]
+aborigines     aborigines[Noun]
+abort  faire avorter[Verb]
+aborted        avorté[Verb]
+aborter        avorteur/ avorteuse / faiseuse d'anges[Noun]
+aborting       discontinuant[Adjective]
+abortion       avortement
+abortion       avortement (m)[Noun]
+abortionist    avorteur[Noun]
+abortionists   avorteurs
+abortions      avortements[Noun]
+abortive       manque(e)[Adjective]
+abortively     en vain[Verb]
+aborts avorte, e/choue, abandonne[Verb]
+abound abonder
+abounding      abondant[Adjective]
+about  (approximatly)environ, a peu pres[Adjective]
+above  au-dessus[Adjective]
+aboveboard     re/gulier, correct[Adjective]
+aboveground    au-dessus du sol, a\ la surface[Adjective]
+abovementioned ci-haut mentionné
+abovementioned mentionné ci-dessus[Adjective]
+abracadabra    abracadabra[Verb]
+abradable      qui peut s'e/rafler, qui peut s'e/roder[Adjective]
+abrade user en frottant, e/roder[Verb]
+abrasion       frottement, e/corchure, abrasion[Noun]
+abrasions      Ã©corchures, Ã©gratignures[Noun]
+abrasive       abrasif(ive)[Adjective]
+abrasives      abrasifs[Noun]
+abreast        de front[Adjective]
+abridge        abreger[Verb]
+abridged       abre/ge/[Verb]
+abridgement    re/sume/[Noun]
+abridging      raccourc,ant[Adjective]
+abroad a\ l'e/tranger, au loin[Adverb]
+abrogate       abroger[Verb]
+abrogated      abroge/, aboli[Verb]
+abrogation     abrogation[Noun]
+abrupt abrupte[Adjective]
+abruptly       brusquement[Adjective]
+abruptness     abrupte[Noun]
+abscess        abcès[Noun]
+abscesses      abce\s[Noun]
+abscond        s'enfuir[Verb]
+absconded      s'enfuir (from, de)[Verb]
+absence        absence[Noun]
+absences       absences[Noun]
+absent absent[Adjective]
+absentee       absentee[Noun]
+absenteeism    absente/isme[Noun]
+absentees      absentees[Noun]
+absently       distraitement[Adverb]
+absentminded   distrait[Adjective]
+absentmindedly d'un air distrait[Adverb]
+absentmindedly distraitement[Adverb]
+absentmindedness       distraction[Noun]
+absinth        absinthe[Noun]
+absinthe       absinthe[Noun]
+absolute       absolu[Adjective]
+absolutely     absolument[Adverb]
+absolution     absolution[Noun]
+absolutism     absolutisme[Noun]
+absolve        absoudre[Verb]
+absolved       exone/re/[Adjective]
+absolving      exon/erant[Adjective]
+absorb absorber, retenir, assimiler[Verb]
+absorbability  absorbabilite/[Adjective]
+absorbable     absorbable[Adjective]
+absorbant      absorbant[Adjective]
+absorbed       absorb/e[Adjective]
+absorbent      absorbant(e)[Adjective]
+absorbing      absorbant[Adjective]
+absorption     absorbtion[Noun]
+abstain        abstenir[Verb]
+abstained      absteni[Adjective]
+abstemious     frugal(e), sobre[Adjective]
+abstention     abstention[Noun]
+abstentions    abstentions[Noun]
+abstinence     abstinence[Noun]
+abstinent      sobre[Adjective]
+abstinently    sobrement[Adverb]
+abstract       abstrait[Adjective]
+abstract       résumé, abrégé[Noun]
+abstraction    distraction, abstraction[Noun]
+abstruse       abstrus(e)[Adjective]
+absurd absurde[Adjective]
+absurdism      absurdisme[Noun]
+absurdist      absurdiste[Noun]
+absurdities    absurdite/s[Noun]
+absurdity      absurdite/[Noun]
+abundance      abondance[Noun]
+abundant       abondant[Adjective]
+abundantly     abondamment[Adjective]
+abuse  abus[Noun]
+abused abuse/[Verb]
+abused insulter[Verb]
+abusive        abusif[Adjective]
+abusively      abusivement[Adverb]
+abut   etre contigu(ë) Ã [Verb]
+abuzz  bourdonnant[Adjective]
+abysmal        Ã©pouvantable, abominable[Noun]
+abysmally      abominablement[Adverb]
+abyss  abysse[Noun]
+abyss  abi^me[Noun]
+abysses        abysses[Noun]
+abysses        abi^mes[Noun]
+acacia acacia[Noun]
+academic       académique[Adjective]
+academical     acade/mique[Adjective]
+academically   acade/miquement[Adverb]
+academician    acade/micien[Noun]
+academies      academies[Noun]
+academism      academisme[Noun]
+academy        académie[Noun]
+acanthus       acanthe[Noun]
+acanthuses     acanthes[Noun]
+accede acce/der[Verb]
+accede consentir[Verb]
+accelerate     acce/le/rer[Verb]
+accelerated    accéléré[Adjective]
+acceleration   acce/le/ration[Noun]
+accelerations  acce/le/rations[Noun]
+accelerator    acce/le/rateur[Noun]
+accelerators   acce/le/rateurs[Noun]
+accelerometer  acce/le/rome\tre[Noun]
+accelerometers acce/le/rome\tres[Noun]
+accent accent[Noun]
+accented       accente/[Verb]
+accented       accentue/
+accents        accents[Noun]
+accentual      accentuelle[Adjective]
+accentually    accentuellement[Adverb]
+accentuate     accentuer[Verb]
+accentuated    accentue/[Adjective]
+accentuation   accentuation[Noun]
+accept accepter[Verb]
+acceptability  acceptabilite/[Noun]
+acceptable     acceptable[Adjective]
+acceptably     convenablement[Adverb]
+acceptance     acceptation[Noun]
+accepted       accepte/[Verb]
+accepter       accepteur[Noun]
+acceptor       accepteur[Noun]
+access acce\s, acce/der (verb)[Noun]
+accessed       accesse/[Verb]
+accessibility  accessibilite/[Noun]
+accessible     accessible[Adjective]
+accession      accession[Noun]
+accessorial    accessoire[Adjective]
+accessories    accessoires[Noun]
+accessorize    accessoriser[Verb]
+accessors      accesseurs[Noun]
+accessory      accessoire[Noun]
+accident       accident[Noun]
+accidental     accidentel[Adjective]
+accidentalism  accidentalisme[Noun]
+accidentalist  accidentaliste[Noun]
+accidentally   accidentellement[Adverb]
+accidently     accidentalement[Adverb]
+accidents      accidents[Noun]
+acclaim        acclamer[Verb]
+acclamation    acclamation[Noun]
+acclimate      acclimater[Verb]
+acclimated     acclimate/[Adjective]
+acclimatize    acclimater[Verb]
+accolade       accolade[Noun]
+accolades      accolades[Noun]
+accommodate    accomoder[Verb]
+accommodated   accommode/[Verb]
+accommodating  obligeant(e)[Adjective]
+accommodation  accomodation[Noun]
+accommodations accommodations[Noun]
+accompanied    accompagne/[Adjective]
+accompanier    accompagneur[Noun]
+accompanies    accompanies[Verb]
+accompaniment  accompagnement[Noun]
+accompaniments accompagnements[Noun]
+accompanist    accompaniste[Noun]
+accompanists   accompanistes[Noun]
+accompany      accompagner, accompagner qqn (à)[Verb]
+accompanyist   accompagnateur[Noun]
+accompanyists  accompagnateurs[Noun]
+accomplice     complice[Noun]
+accomplices    complices[Noun]
+accomplish     accomplir[Verb]
+accomplished   accompli(e)[Adjective]
+accomplishment accomplissement[Noun]
+accomplishments        accomplissements[Noun]
+accord accord[Noun]
+accordance     in accordance with : en conformite/ avec
+accorder       accordeur[Noun]
+accorders      accordeurs[Noun]
+accordion      accorde/on[Noun]
+accordionist   accordionist     accordioniste[Noun]
+accordionists  accordionists     accordionistes[Noun]
+accordions     accorde/ons[Noun]
+accords        accords[Noun]
+accost accoster[Verb]
+account        compte[Noun]
+accountability responsibilité[Noun]
+accountable    responsable[Adjective]
+accountant     comptable[Noun]
+accounting     comptabilité
+accouterment   accoutrement[Noun]
+accredited     accredite/[Verb]
+accrued        accrue/[Verb]
+accruement     accruement[Noun]
+accumulated    accumule/[Verb]
+acetaminophen  ace/taminophe\n[Noun]
+acetify        acetifie/[Verb]
+acetone        acetone[Noun]
+acid   acide[Noun]
+acidic acidique[Adjective]
+admission      aveu[Adverb]
+allergen       allergene
+allergen       allergene[Noun]
+allergic       alergique[Adjective]
+allergies      allergies
+allergies      allergies[Noun]
+allergy        allergie
+allergy        allergie[Noun]
+alleviate      apaiser, soulager[Verb]
+alleviated     apaise/, apaise/e[Adjective]
+alley  ruelle, alle/e
+alley  ruelle, allée[Noun]
+alleys ruelles, alle/es
+alleys ruelles, alle/es[Noun]
+alliance       alliance
+alliance       alliance[Noun]
+alliances      alliances
+alliances      alliances[Noun]
+allied allie/, allie/e
+allied allie/, allie/e[Adjective]
+alligator      alligator
+alligator      alligator[Noun]
+alligators     alligators
+alligators     alligators[Noun]
+alliteration   allite/ration
+alliteration   allite/ration[Noun]
+alliterations  allite/rations
+alliterations  allite/rations[Noun]
+allocate       attribuer[Verb]
+allocated      attibue/, attribue/e[Adjective]
+allocation     attribution
+allocation     attribution[Noun]
+allocations    attibutions
+allocations    attributions[Noun]
+allocution     allocution
+allocution     attribution[Noun]
+allocution     allocution[Noun]
+allot  assigner[Verb]
+allow  autoriser, permettre[Verb]
+allowable      admissible[Adjective]
+allowance      indemnité[Noun]
+allowed        autorise/, autorise/e[Adjective]
+alloy  alliage[Noun]
+alphabet       alphabet[Noun]
+alphabetic     alphabetique[Adjective]
+alphabetical   alphabetique[Adjective]
+alphabetically alphabetiquement[Adverb]
+alphabetization        alphabetisation[Noun]
+alphabetizations       alphabetisations[Noun]
+alphabetize    alphabetiser[Verb]
+alphabetized   alphabetise[Adjective]
+alphabetizing  alphabetizer[Verb]
+alphabets      alphabets[Noun]
+alphamerical   alphanumerique[Adjective]
+alphanumeric   alphanumerique[Noun]
+alphanumerical alphanumerique[Adjective]
+alphanumerically       alphanumeriquement[Adverb]
+alphanumerics  alphanumerique[Adverb]
+alpine alpin[Adjective]
+alpinism       alpinisme[Noun]
+alpinist       alpiniste[Noun]
+already        deja[Conjunction]
+also   aussi[Conjunction]
+altercation    altercation[Noun]
+altercations   altercations[Noun]
+alternate      alterner[Verb]
+alternated     alterne[Adjective]
+alternately    alternativement[Adverb]
+among  parmi, entre[Preposition]
+amoral amoral[Adjective]
+amorous        amoureux[Adjective]
+amorously      amoureusement, avec amour[Adverb]
+amorphous      amorphe[Adjective]
+amount s'elever. monter[Verb]
+amount somme, quantite, importance[Noun]
+amp    ampere ; amplifier[Noun]
+ampere ampere[Noun]
+ampersand      et commercial ; esperluette[Noun]
+amphetamine    amphetamine[Noun]
+and    et[Preposition]
+anyway En tout cas, de toute facon[Adverb]
+anywhere       n'importe ou ; partout[Adverb]
+aorta  aorte[Noun]
+apace  rapidement[Adverb]
+apart  a part, separe[Adjective]
+apartheid      apartheid[Noun]
+apartment      apartement, chambre[Noun]
+apathetic      apathique[Adjective]
+apathy apathie, indifference[Noun]
+ape    singe[Noun]
+ape    singer[Verb]
+aperitif       aperitif[Noun]
+aperture       ouverture[Noun]
+apex   sommet[Noun]
+aphid  aphis; puceron[Noun]
+arrive arrivant[Verb]
+aspen  abedul
+audit  audit[Noun]
+auditorium     auditorium[Noun]
+auditoriums    auditoriums[Noun]
+audits audits[Verb]
+available      disponible
+babble bavard[Verb]
+babbler        bavardent
+babies be/be/s[Noun]
+baboon babouin
+baby   be/be/[Noun]
+baccalaureate  baccalaure/at[Noun]
+baccarat       baccarat[Noun]
+bachelor       ce/libataire[Noun]
+bachelors      ce/le/bataires[Noun]
+bacilli        bacilles (noun masculine)[Noun]
+bacillus       bacille (noun masculine)[Noun]
+back   en arriere, en retour
+backache       douler de dos
+backbite       calumnier
+backbone       e/pine[Noun]
+background     arriere-plan
+backgrounds    arriere-plans
+backside       derrie\re[Noun]
+backslide      re/gresser[Verb]
+backup (computer) sauvegarde (feminine)[Noun]
+backward       en arrie\re[Preposition]
+bacon  lard
+bacteria       bactérie
+bad    mauvais, torve
+badge  insigne
+badged insignée
+badgers        blaireaux
+badinage       badinage
+bag    sac[Noun]
+bagatelle      bagatelle
+bagatelles     bagatelles
+baggage        effets, colis
+bags   fouilles, Ã©tuis, sacs
+baguette       baguette
+bah    bannir[Verb]
+bail   caution
+bairn  enfant (e/cossais)[Noun]
+bait   leurre, eche
+bake   faire cuire[Verb]
+baker  boulanger
+bakeries       boulangeries
+bakers boulangers
+bakery boulangerie
+bakeshop       boulangerie[Noun]
+balance        balance, Ã©quilibrer
+balconies      balcons
+balcony        balcon
+bald   chauve, Ã  ras
+baldhead       chauve[Adjective]
+baldly ouvertement[Adverb]
+baldness       calvitie[Noun]
+bale   ballot
+baleen baleine
+balk   déjouer[Verb]
+ball   bal (dance), ballon (like for games)
+ballad ballade
+ballade        ballade
+ballads        ballades
+ballast        ballast, lest
+ballet ballet
+balletic       balletique
+balloon        ballon, aérostat
+ballot ballot
+balls  bals[Noun]
+ballyhoo       publicite/[Noun]
+balm   baume[Noun]
+bamboo enfant (italien)[Noun]
+bamboozle      tricher[Verb]
+banana banane
+bananas        bananes
+band   bande, chapelle
+bandage        bandage
+bandeau        bandeau
+bandit brigand, forban, bandit
+bandits        brigands, forbans, bandits
+bandleader     chef d'orchestre[Noun]
+bandmaster     chef d'orchestre[Noun]
+bane   poison[Noun]
+banished       banni[Adjective]
+barb   barbe[Noun]
+barbarian      barbare[Noun]
+barbarians     barbares[Noun]
+barbarism      barbarisme[Noun]
+barber barbier[Noun]
+barmaid        serveuse[Noun]
+barman serveur[Noun]
+barracks       casernes[Noun]
+beach  plage[Noun]
+bear   ours[Noun]
+bear   supporter[Verb]
+bed    lit[Noun]
+bedroom        chambre (a coucher)[Noun]
+believe        croire[Verb]
+betray trahir[Verb]
+bibliographic  bibliographique[Adjective]
+bibliographies bibliographies[Noun]
+bibliography   bibliographie[Noun]
+blackberry     zarzamorra[Noun]
+bonjour        hello
+book   livre (m)
+boomerang      boomerang (m)
+boxer  (~ shorts) caleçon[Noun]
+boy    garc,on[Noun]
+boys   garc,ons[Noun]
+brain  cerveaux[Noun]
+brood  rimuginare, covare[Verb]
+broom  balai
+broth  bouillon
+build  construire[Verb]
+building       ba^timent[Noun]
+bye    bon voyage, ciao[Preposition]
+cab    taxi[Noun]
+cabal  cabale[Noun]
+cabala cabale[Noun]
+cabalism       cabalisme[Noun]
+cabalist       cabaliste[Noun]
+cabalistic     cabalistique[Adjective]
+caballero      cavalier[Noun]
+cabaret        cabaret[Noun]
+cabbage        chou[Noun]
+cabbages       choux[Noun]
+cabdriver      chauffeur de taxi[Noun]
+cabin  cabane[Noun]
+cabinet        cabinet[Noun]
+cabinetmaker   e/be/niste[Noun]
+cabinetmakers  e/be/nistes[Noun]
+cabinets       cabinets[Noun]
+cabins cabanes,(ships)cabines[Noun]
+cable  ca^ble[Noun]
+cabled cablé[Adjective]
+cablegram      ca^blogramme[Noun]
+cablegrams     ca^blogrammes[Noun]
+cables ca^bles[Noun]
+cabling        cablage[Noun]
+cabman cocher de fiacre[Noun]
+caboose        caboose[Noun]
+cabotage       cabotage[Noun]
+cabriolet      cabriolet[Noun]
+cabs   taxis[Noun]
+cacao  cacao[Noun]
+cacciatore     chasseur[Noun]
+cachalot       cachalot[Noun]
+cache  cachette[Noun]
+cachepot       cachepot[Noun]
+caches cachettes[Noun]
+cackle caquet[Noun]
+cackled        caquete/[Verb]
+cackles        caquets[Noun]
+cackling       caquetant[Verb]
+cacophony      cacophonie[Noun]
+cacti  cactus(plural)[Noun]
+cactus cactus (singular)[Noun]
+cad    mufle[Noun]
+cadaver        cadavre
+cadaverous     terreux,[Adjective]
+caddies        boi^tes a\ the/[Noun]
+caddy  boii^te a\ the/[Noun]
+cadence        cadence[Noun]
+cadet  cadet, younger son[Noun]
+cadetship      brevet de cadet[Noun]
+cadge  mendier[Verb]
+cadger mendiant[Noun]
+cafe   cafe/-restaurant[Noun]
+cafes  cafe/-restaurants[Noun]
+cafeteria      cafe/taria[Noun]
+cafeterias     cafe/tarias[Noun]
+caffeine       cafe/ine[Verb]
+caftan caftan[Noun]
+cage   cage[Noun]
+cages  cages[Noun]
+cahier copy book[Noun]
+cairn  cairn[Noun]
+cairns cairns[Noun]
+caitiff        la^che[Adjective]
+cajole cajoler[Verb]
+cajoler        cajoleur[Noun]
+cajolery       cajolerie[Noun]
+cake   gâteau[Noun]
+cake   ga^teau[Noun]
+calcium        calcium[Noun]
+calculate      calculer[Verb]
+calculated     calculé
+calibrate      calibrer[Verb]
+calibrated     calibré[Adjective]
+calibration    calibration[Noun]
+car    voiture[Noun]
+carbonization  carbonisation[Noun]
+carbonize      carboniser[Verb]
+carbonized     carbonise[Adjective]
+carbonless     sans carbone[Adjective]
+carburetor     carburateur[Noun]
+carburetors    carburateurs[Noun]
+carburization  carburation[Noun]
+carburize      carburer[Verb]
+card   carte[Noun]
+cardamom       cardamone[Noun]
+cardiac        cardiaque[Adjective]
+cardigan       cardigan[Noun]
+cardioid       cardioide[Noun]
+cardioids      cardioides[Noun]
+care   attention[Noun]
+care   care[Noun]
+cared  attentionne[Adjective]
+career cariere[Noun]
+careful        attentionne[Adjective]
+carefully      avec attention[Adjective]
+cat    le chat[Noun]
+cell   cellule[Noun]
+cellular       cellulaire[Adjective]
+chance hasard
+cherries       les cerises[Noun]
+church e/glise[Noun]
+churches       e/glises[Noun]
+cloak  manteau[Noun]
+cloaks manteaux[Noun]
+clock  horloge[Noun]
+clockmaker     horloger[Noun]
+clockwise      dans le sens des aigu.illes d'une montre
+cloister       cloitre[Noun]
+clone  clone[Noun]
+cloud  le nuage
+c'mon  ben voyons
+coal   charbon (masc.)[Noun]
+computer       ordinateur[Noun]
+computers      ordinateurs[Noun]
+comrades       amis[Noun]
+concealed      e/touffe/
+conjuring      escamotage[Verb]
+contemplate    contempler[Verb]
+contemplate    envisager[Verb]
+contemplate    pre/voir[Verb]
+contemplates   envisage[Verb]
+contemplation  contemplation[Noun]
+contemplation  me/ditation[Noun]
+contemplation  recueillement[Noun]
+contemplations contemplations[Noun]
+contemplations me/ditations[Noun]
+contemplative  contemplatif[Adjective]
+contemporaneous        contemporain[Adjective]
+contemporaneously      en me^me temps que [Adverb]
+contemporaries contemporains[Noun]
+contemporaries de la me^me ge/ne/ration[Adjective]
+contemporary   contemporain[Adjective]
+contemporary   de la me^me ge/ne/ration[Adjective]
+contempt       de/dain[Noun]
+contempt       me/pris[Noun]
+contemptible   indigne[Adjective]
+contemptible   me/prisable[Adjective]
+contemptibly   avec me/pris[Adverb]
+contemptuous   de me/pris[Adjective]
+contemptuous   me/prisant[Adjective]
+contemptuously avec de/dain[Adverb]
+contemptuously avec me/pris[Adverb]
+contend        combattre[Verb]
+contend        disputer[Verb]
+contend        lutter[Verb]
+contender      candidat[Noun]
+contender      challenger[Noun]
+contender      concurrent[Noun]
+contenders     candidats[Noun]
+contenders     challengers[Noun]
+contenders     concurrents[Noun]
+contending     concurrents[Adjective]
+contending     oppose/es[Adjective]
+contends       dispute[Verb]
+contends       lutte[Verb]
+content        contenter[Verb]
+content        satisfaire[Verb]
+content        satisfait[Adjective]
+contented      content[Adjective]
+contented      satisfait[Adjective]
+contentedly    avec contentement[Adverb]
+contentedness  contentement[Noun]
+contention     dispute[Noun]
+contention     e/mulation[Noun]
+contention     lutte[Noun]
+contentions    disputes[Noun]
+contentions    e/mulations[Noun]
+contentions    luttes[Noun]
+contentious    contentieux[Adjective]
+contentious    querelleur[Adjective]
+contentment    contentement[Noun]
+contents       contenu[Noun]
+contents       table de matie\res[Noun]
+contest        combat[Noun]
+contest        concours[Noun]
+contest        contester[Verb]
+contestant     combattant[Noun]
+contestant     concurrent[Noun]
+cot    lit d'enfant[Noun]
+coterie        coterie[Noun]
+cotillion      cotillon[Noun]
+cotillon       cotillon[Noun]
+cottage        chaumie\re[Noun]
+cottager       paysan[Noun]
+couch  couche[Noun]
+cough  tousser[Verb]
+coughs toux[Noun]
+count  compter[Verb]
+countenance    visage[Noun]
+counteract     neutraliser[Verb]
+counterbalance contrepoids[Noun]
+counterfeit    contrefait[Adjective]
+countermand    contremander[Verb]
+countermarch   contremarche[Noun]
+counterplot    contre-ruse[Noun]
+counterpoint   contrepoint[Noun]
+counterpoise   contre-balancer[Verb]
+counterweight  contrepoids[Noun]
+countess       comtesse[Noun]
+countless      innombrable[Adjective]
+country        pays[Verb]
+countryman     concitoyen[Noun]
+countrywide    concitoyenne
+county comte/[Noun]
+couple couple[Noun]
+couplet        distique[Noun]
+coupon coupon[Noun]
+courage        courage[Noun]
+courageous     courageux[Adjective]
+courageously   cougrageusement[Adjective]
+courier        courrier[Noun]
+course cours[Noun]
+courser        coursier[Noun]
+court  cour[Noun]
+courteous      courtois[Adjective]
+courteously    courtoisement[Adverb]
+courteousness  courtoisie[Noun]
+courtesy       courtoisie
+courthouse     palais de justice[Noun]
+courtier       courtisan[Noun]
+courtliness    e/le/gance[Adjective]
+courtly        e/le/gant[Adjective]
+courtmartial   conseil de guerre[Noun]
+courtroom      salle d'audience[Noun]
+courtship      cour[Noun]
+cousin cousin[Noun]
+cove   anse[Noun]
+covenant       convention[Noun]
+cover  couvrir[Verb]
+covert cache/[Adjective]
+covet  covoiter[Adjective]
+covetous       avide[Adjective]
+covetously     avidement[Adjective]
+cow    la moo cowetta[Noun]
+cow    la vache[Noun]
+coward la^che[Noun]
+cowardice      la^chete/
+cowardly       la^che[Adjective]
+cower  se blottir[Verb]
+cowherd        vacher[Noun]
+cowl   capuchon[Noun]
+coxcomb        petit-mai^tre[Noun]
+coy    farouche[Adjective]
+coyly  modestement[Adverb]
+coyness        re/serve[Noun]
+coyote coyote[Noun]
+cozily confortablement[Adverb]
+cozy   confortable
+crab   cancre[Noun]
+crabapple      pomme sauvage[Noun]
+crabbed        maussade[Adjective]
+crack  fente[Noun]
+cracker        pe/tard[Noun]
+crackle        craqueter[Verb]
+cradle berceau[Noun]
+craft  fourberie[Noun]
+craftily       astucieusement[Adverb]
+crag   rocher escarpe/[Noun]
+cram   fourrer[Verb]
+cramp  crampe[Noun]
+cranberry      airelle coussinette[Noun]
+crane  grue[Noun]
+cranium        cra^ne[Noun]
+crank  manivelle[Noun]
+crankiness     humeur difficile[Noun]
+cranky d'humeur difficile[Adjective]
+crape  cre^pe[Noun]
+crash  retentir[Verb]
+crate  caisse a\ claire-voie[Noun]
+crater crate\re[Noun]
+crave  de/sirer ardemment[Verb]
+craven poltron[Adjective]
+crawl  ramper[Verb]
+crayfish       e/crevisse[Noun]
+crayon pastel[Noun]
+craze  manie[Noun]
+crazily        follement[Adverb]
+crazy  fou[Adjective]
+creak  grincer[Verb]
+cream  cr\eme[Noun]
+creamy cre/meux[Adjective]
+crease plisser[Verb]
+create cre/er[Verb]
+creation       cre/ation
+creator        cre/ateur[Noun]
+creature       cre/ature[Noun]
+credence       croyance[Noun]
+credential     certificat[Noun]
+credit cre/dit[Noun]
+creditable     estimable
+creditably     honourablement[Adverb]
+creditor       cre/ancier[Noun]
+credo  crois[Verb]
+credulity      cre/dulite/[Noun]
+credulous      cr/edule[Adjective]
+credulously    cr/edulement[Adverb]
+creed  credo[Noun]
+creek  crique[Noun]
+creep  ramper[Verb]
+creeps chair de poule[Noun]
+cremate        incin/erer[Verb]
+cut    couper[Verb]
+cute   mignon, charmant, adorable[Adjective]
+cute   mignonne[Adjective]
+cuteness       gentillesse, charme[Noun]
+cutoffs        limite, seuil[Noun]
+cutout forme a\ de/couper[Noun]
+cuts   e/conomies, re/duction de budget[Noun]
+cutter couteau (de de/coupage)[Noun]
+cutting        d/ecoupe, de/coupage[Noun]
+cyanate        cyanante[Noun]
+cyanide        cyanure[Noun]
+cybernetic     cyberne/tique[Adjective]
+cybernetician  cyberne/ticien[Noun]
+cybernetics    cyberne/tique[Noun]
+cycle  cycle[Noun]
+cyclic cyclique[Adjective]
+cyclical       cyclique[Adjective]
+cyclist        cycliste[Noun]
+cyclists       cyclistes[Noun]
+cycloid        cycloi.de[Noun]
+cycloidal      cycloi.dal[Adjective]
+cyclone        cyclone[Noun]
+cyclonic       cyclonique[Adjective]
+cyclopean      cyclope/en[Adjective]
+cyclotron      cyclotron[Noun]
+cylinder       cylindre[Noun]
+dad    papa[Noun]
+daddies        papas[Noun]
+daddy  papa[Noun]
+dads   papas[Noun]
+daffy  barjot[Adjective]
+daft   barje[Adjective]
+dagger dague (une)[Noun]
+dahlia dahlia[Noun]
+dahlias        dahlias[Noun]
+daily  quotidien
+daintier       plus délicat
+dainty délicat
+dairy  laitier
+dalmatian      dalmatien[Adjective]
+dalmatians     dalmatiens[Noun]
+dam    barrage[Noun]
+damage abimer[Verb]
+damage de/ga^t[Noun]
+damage endommagement
+damage endommager[Verb]
+damaged        endommage/[Adjective]
+damaged        endommagé[Adjective]
+damager        endommageur
+damagers       endommageurs
+damages        de/ga^ts[Noun]
+damaging       endommageant
+dame   dame
+dammit merde alors
+damnation      damnation[Noun]
+damned damne/[Adjective]
+damp   humide[Adjective]
+dampen humidifier[Verb]
+dampened       humidifie/
+dampness       humidite/[Noun]
+dams   barrages[Noun]
+dance  danse
+dancer danceur
+dancers        danceurs
+dancing        danser[Verb]
+dandelion      pissenlit
+dandelions     pissenlits
+dandies        dandys[Noun]
+dandruff       pelicule[Noun]
+danger danger[Noun]
+dangerous      dangereux[Adjective]
+d'art  d'art
+day    jour[Noun]
+daybreak       aube[Noun]
+daylight       lumiere du jour[Noun]
+days   jours[Noun]
+deactivate     de/sactiver[Verb]
+deactivation   de/sactivation[Noun]
+dead   mort[Adjective]
+deaf   sourd[Adjective]
+deaths morts
+deep   profond[Adjective]
+density        densite/[Noun]
+deserve        meriter[Verb]
+d'etat d'état
+d'etre d'être
+device pe/riph/erique[Noun]
+device pe/riphe/rique[Noun]
+dictated       dicté[Verb]
+dictates       dicte[Verb]
+dictation      dictée[Noun]
+dictations     dictées[Noun]
+dictionaries   dictionnaires[Noun]
+dictionary     dictionnaire[Noun]
+did    a fait[Verb]
+die    mourir[Verb]
+died   mort[Verb]
+diesel diesel[Noun]
+diet   diète[Noun]
+dietetically   diététiquement[Adverb]
+diets  diètes[Noun]
+different      différent[Adjective]
+difficulties   difficultés[Noun]
+difficulty     difficulté[Noun]
+dig    creuser[Verb]
+digested       digéré[Verb]
+dignitaries    dignitaires[Noun]
+dignities      dignités[Noun]
+dignity        dignité[Noun]
+dilate dilater[Verb]
+dilated        dilaté[Verb]
+doctor docteur[Noun]
+document       document[Noun]
+d'oeuvre       d'oeuvre
+dog    chien/ne[Noun]
+doggie chien/ne[Noun]
+dogs   chiens[Noun]
+drink  boire[Verb]
+drinks boissons[Noun]
+drive  conduire[Verb]
+driver conducteur[Noun]
+drizzle        bruiner[Verb]
+dry    se/cher[Verb]
+duck   canard[Noun]
+each   chaque
+eagle  aigle[Noun]
+eagles aigles[Noun]
+eaglet aiglon[Noun]
+ear    oreille[Noun]
+earache        mal d'oreille[Noun]
+eardrum        tympan[Noun]
+eardrums       tympans[Noun]
+earlobe        lobe d'oreille[Noun]
+early  to^t[Adjective]
+earn   gagner[Verb]
+earning        gagner[Verb]
+earphones      e/couteurs[Noun]
+earring        boucle d'oreille[Noun]
+earrings       boucles d'oreille[Noun]
+ears   oreilles[Noun]
+earth  terre[Noun]
+earthquake     tremblement de terre[Noun]
+earthquakes    tremblements de terre[Noun]
+earths terres[Noun]
+earthworm      ver de terre[Noun]
+earthworms     vers de terre[Noun]
+earwax serumen[Noun]
+ease   facilite/[Noun]
+easel  chevalet[Noun]
+easier plus facile[Adjective]
+easiest        le plus facile[Adjective]
+easily facilement[Adverb]
+easiness       facilite/[Noun]
+east   est[Noun]
+easter Pa^ques[Noun]
+easy   facile[Adjective]
+eat    manger[Verb]
+eatable        comestible[Adjective]
+eats   manger[Verb]
+ebony  e/be\ne[Noun]
+eccentric      excentrique[Adjective]
+eccentricity   excentricite/[Noun]
+ecclesiastic   eccle/siastique[Noun]
+echo   e/cho[Noun]
+eclipse        e/clipse[Noun]
+ecologic       e/cologique[Adjective]
+ecologist      e/cologiste[Noun]
+ecology        e/cologie[Noun]
+economics      econom'ica[Noun]
+ecru   e/cru[Adjective]
+eight  huit[Adverb]
+eighteen       dix-huit[Adverb]
+eighteenth     dix-huitie\me[Adjective]
+eightfold      huit fois[Adverb]
+eighth huitie\me[Adjective]
+eighties       les anne/es quatre-vingt (f)[Noun]
+eightieth      quatre-vingtie\me[Adjective]
+eighty quatre-vingt[Adverb]
+eightyfold     quatre-vingt fois[Adverb]
+einsteinium    einsteinium (m)[Noun]
+either soit[Adverb]
+ejaculate      e/jaculer[Verb]
+ejaculated     e/jacule/[Adjective]
+ejaculates     e/jacule[Verb]
+ejaculating    e/jaculant[Adjective]
+ejaculation    e/jaculation (f)[Noun]
+ejaculations   e/jaculations (f)[Noun]
+ejaculatory    e/jaculatoire[Adjective]
+eject  e/jecter[Verb]
+ejectable      e/jectable[Adjective]
+ejecting       e/jectant[Verb]
+ejection       e/jection (f)[Noun]
+ejector        e/jecteur (m)[Noun]
+ejectors       e/jecteurs (m)[Noun]
+elaborate      e/laborer[Verb]
+elaborated     e/labore/ (m), e/labore/e (f)[Adjective]
+elaborates     e/labore[Verb]
+elaborating    e/laborant[Adjective]
+elaboration    e/laboration (f)[Noun]
+elaborations   e/laborations (f)[Noun]
+elevator       ascenseur[Noun]
+eleven onze[Adjective]
+eleventh       onzie\me[Noun]
+eliminate      e/liminer[Verb]
+end    fin[Noun]
+environment    ambiente[Noun]
+environmental  ambiental[Adjective]
+envoy  enviado[Noun]
+envy   envidia[Noun]
+envy   envidiar[Verb]
+escalator      escalier roulant[Noun]
+establish      constater[Verb]
+event  occasion[Noun]
+eventual       final[Adjective]
+eventually     finallement[Adverb]
+ever   toujours[Adverb]
+evergreen      permanent[Adjective]
+everlasting    permanent[Adjective]
+every  chaque[Pronoun]
+everywhere     partout[Conjunction]
+eviction       mise a` l' e'cart[Noun]
+evidence       preuve[Noun]
+exclaim        s'exclaimer[Verb]
+fable  fable[Noun]
+fables fables[Noun]
+fabric tissu[Noun]
+fabricant      fabricant[Noun]
+fabricate      fabriquer[Verb]
+fabricated     fabrique/[Pronoun]
+fabricates     fabrique[Verb]
+fabricating    fabriquant[Verb]
+fabrication    invention(s), fabulation; fait, forge(e) de toutes pieces[Noun]
+fabrications   fabrications[Noun]
+fabricator     fabricant[Noun]
+fabricators    fabricants[Noun]
+fabrics        tissus[Noun]
+fabulist       fabuliste (m)[Noun]
+fabulous       fabuleux(euse);  formidable[Adjective]
+facade fac,ade[Noun]
+facades        fac,ades[Noun]
+face   visage, figure; expression; (of clock) cadran;  (of building) facade[Noun]
+faceless       sans face[Noun]
+faceplate      face avant (f),panneau avant (m)[Noun]
+facet  facette[Noun]
+facetious      facétieux[Adjective]
+facetious      plaisant[Adjective]
+facetiously    facétieusement[Adverb]
+facial facial[Adjective]
+facies facie\s (m)[Noun]
+facile facile[Adjective]
+facilitate     faciliter[Verb]
+facilitated    facilite/[Pronoun]
+facilitates    facilite[Verb]
+facilitating   facilitant[Verb]
+facilities     instalations[Noun]
+facility       usine (f), e/tablissement (m)[Noun]
+facing face a, en face de[Preposition]
+facsimile      (document) telecopie; (machine) telecopieur[Noun]
+fact   fait[Noun]
+faction        faction[Noun]
+factor facteur[Noun]
+factorial      factoriel
+factorials     factorielles (f)[Noun]
+factories      usines (f)[Noun]
+factorization  factorisation[Noun]
+factorizations factorisations[Noun]
+factorize      factoriser[Verb]
+factorized     factorisé[Adjective]
+factors        facteurs (m)[Noun]
+factory        usine (m)
+facts  faits[Noun]
+factual        factuel (m),factuelle (f)[Adjective]
+facultative    facultatif[Adjective]
+facultatively  facultativement[Adverb]
+faculties      faculte/s (f)[Noun]
+faculty        faculté
+fad    affaiblir, atte/nuer[Verb]
+fade   se faner[Verb]
+faded  affaibli, atte/nue/[Adjective]
+fader  atte/nuateur (m)[Noun]
+faders atte/nuateurs (m)[Noun]
+fading affaiblissement (m), atte/nuation (f)[Noun]
+faery  fe/e[Noun]
+faience        fai.ence
+fail   Ã©chouer[Verb]
+faint  s'e/vanouir[Verb]
+faintly        faiblement[Adverb]
+fair   juste[Adjective]
+fairly e/quitablement[Adverb]
+fairy  fe/e[Noun]
+faith  foi[Noun]
+faithful       fide\le[Adjective]
+faithfully     fide\lement[Adverb]
+fashion        mode[Noun]
+fashionable    a\ la mode[Adjective]
+fast   rapide[Adjective]
+fasten attacher[Verb]
+fastener       fermeture[Noun]
+fastidious     exigeant[Adjective]
+fat    gros[Adjective]
+fatal  mortel[Adjective]
+fatalism       fatalisme[Noun]
+fatality       victime[Noun]
+fatally        mortellement[Adverb]
+fate   destin[Noun]
+fish   poisson[Noun]
+fishable       pêchable[Adverb]
+fishbowl       bôl Ã  poisson[Noun]
+fished pêché[Verb]
+fisher pêcheur[Noun]
+fisheries      poissonneries[Noun]
+fisherman      pêcheur[Noun]
+fishermen      pêcheurs[Noun]
+fishers        pêcheurs[Noun]
+fishery        poissonnerie[Noun]
+fishes poissons[Noun]
+fishing        Ã  la pêche
+fishtail       queue-de-poisson[Noun]
+fission        fision[Noun]
+fissionable    fisionable[Adverb]
+fissure        fissure[Noun]
+fist   poing[Noun]
+fisted poingé[Verb]
+fistful        poingée[Noun]
+five   cinq[Adverb]
+fivefold       cinq fois[Adverb]
+fix    re/parer[Verb]
+fixation       fixation (f)[Noun]
+fixations      fixations (f)[Noun]
+fixity fixite/ (f)[Noun]
+fixture        support (m)[Noun]
+fixtures       supports (m)[Noun]
+fjord  fjord (m)[Noun]
+fjords fjords (m)[Noun]
+flight le vol[Noun]
+floppy disquette[Noun]
+fluently       couramment[Adverb]
+foot   pied[Noun]
+football       football[Noun]
+forget oublier[Verb]
+forgetful      oublieux[Adjective]
+forgetfulness  manque de me/moire[Noun]
+forgivable     excusable[Adjective]
+forgivably     de fac,on excusable[Adverb]
+forgive        pardonner[Verb]
+forgiveness    pardon[Noun]
+forgives       pardonne[Verb]
+forgiving      indulgent[Adjective]
+forgo  renoncer \a[Verb]
+forgoes        renonce \a[Verb]
+forgotten      oublie/[Adjective]
+forlorn        de/laisse/[Adjective]
+formaldehyde   formalde/hyde
+four   quatre[Adverb]
+fox    renard (m)[Noun]
+fractal        fractale (f)[Noun]
+fractals       fractales (f)[Noun]
+fraction       fraction (f)[Noun]
+fractionate    fractionner[Verb]
+fraternal      fraternel[Adjective]
+fraternize     fraterniser[Verb]
+friend ami[Noun]
+friendship     Amitie[Noun]
+fringe frange[Noun]
+frog   grenouille[Noun]
+frogs  grenouilles[Noun]
+from   de
+front  devant[Preposition]
+fucked foutu[Adjective]
+fudge  sucre a` la cre`me[Noun]
+fugue  fugue[Noun]
+fulgurant      fulgurant[Adjective]
+funk   frouse[Noun]
+funniest       le plus amusant[Adjective]
+funny  amusant[Adjective]
+gab    bavarde[Verb]
+gabardine      gabardine[Noun]
+gabber comme\re[Noun]
+gabbing        bavarder[Verb]
+gaberdine      une gabardine[Noun]
+gadget un gadget[Noun]
+gaiety la gaieté[Noun]
+gaily  gaiement[Adverb]
+gain   le gain[Noun]
+gained gagne/[Verb]
+gaining        gagnant[Verb]
+gala   un gala[Noun]
+galactic       galactique[Adjective]
+galaxies       galaxies[Noun]
+galaxy une galaxie[Noun]
+gallant        gallant[Adjective]
+gallantly      gallamment[Adverb]
+gallantry      la gallantrie[Noun]
+galleries      galleries[Noun]
+gallery        gallerie[Noun]
+gallon un gallon[Noun]
+gallop galloper[Verb]
+galloped       gallope/[Verb]
+galloping      gallopant[Verb]
+galvanic       galvanique[Adjective]
+galvanism      le galvanisme[Noun]
+galvanize      galvaniser[Verb]
+galvanized     galvanise/[Verb]
+game   un jeu[Noun]
+games  joues[Noun]
+garlic ail[Noun]
+gas    essence[Noun]
+gasoline       essence[Noun]
+ghostwriter    négre[Noun]
+gift   cadeau[Noun]
+gifts  cadeaux[Noun]
+go     aller[Verb]
+goal   objectif[Noun]
+goals  buts
+goat   oie
+god    dieu
+goddess        de/esse
+goddesses      de/esses
+godfather      parrain[Noun]
+golf   golf
+golfer geolfeur
+golfers        golfeurs
+golfs  golfs
+good   bon;bien
+good   bien
+goodbye        au revoir
+goodnight      bon nuit
+gopher gopher[Noun]
+gospel evangile[Noun]
+gown   la robe
+grab   saisir (an object)[Verb]
+gradient       pente (math.)[Noun]
+gradually      graduellement[Adverb]
+grammar        grammaire (f)[Noun]
+grape  le raisin[Noun]
+grapefruit     le pamplemousse[Noun]
+habilitated    habilite/[Verb]
+habilitation   habilitation[Noun]
+habit  coutume[Noun]
+habitant       habitant[Noun]
+habitants      habitants[Noun]
+habitat        habitat[Noun]
+habitation     demeure[Noun]
+habitual       usuel[Adjective]
+had    se faire avoir
+hand   main[Noun]
+head   tete
+heats  series[Noun]
+heaven paradis[Noun]
+heavy  lourd[Adjective]
+hectare        hectare
+hectares       hectares
+hectoliter     hectolitre
+hedge  haie
+hedgehog       he/risson[Noun]
+heed   suivre[Verb]
+heel   talon
+heeler guerisseur
+heels  talons
+height hauteur
+heir   he/ritier
+held   tenu[Adjective]
+helices        helices[Noun]
+hell   enfer[Noun]
+hello  bonjour[Noun]
+helm   barre[Noun]
+helmet casque[Noun]
+help   aide[Noun]
+hemp   chanvre[Noun]
+hen    poule[Noun]
+herd   troupeau[Noun]
+here   ic,i[Noun]
+heron  huron[Noun]
+hips   flancs[Noun]
+hit    frapper[Verb]
+hockey hockey[Noun]
+hogwash        non sense[Noun]
+holidayer      vacancier[Noun]
+holidays       vacances
+home   maison[Noun]
+homeless       sans-abri[Noun]
+homes  maisons[Noun]
+house  maison[Noun]
+ice    glace[Noun]
+instancing     instanciation[Noun]
+internship     stage professionnel en entreprise ou ailleurs
+jab    planter[Verb]
+jabber baragouiner[Verb]
+jabberwocky    (playing card) valet[Noun]
+jabberwocky    Jaseroque, Bredoulocheux, Berdouilleux, Jabberwocheux[Noun]
+jack   criq[Noun]
+jack   valet[Noun]
+jackal chacal[Noun]
+jackals        chacaux[Noun]
+jackass        a^ne[Noun]
+jackdaw        choucas (m)[Noun]
+jacket blouson[Noun]
+jacket veste[Noun]
+jackhammer     marteau piqueur[Noun]
+jackknife      canif[Noun]
+jackpot        gros lot[Noun]
+jade   jade[Noun]
+jaded  brime/e(e)[Adjective]
+jag    bombe, noce[Noun]
+jagged e'bre'che[Verb]
+jail   emprisonner[Verb]
+jail   prison
+jailbreak      evasion[Noun]
+jailed emprisonne/[Adjective]
+jailer geo^lier[Noun]
+jailing        incarce/ration[Noun]
+jailor geo^lier[Noun]
+jails  prisons[Noun]
+jalopy guimbarde[Noun]
+jam    confiture[Noun]
+jam    enfoncer[Verb]
+jamb   jambage[Noun]
+jammed coince/[Adjective]
+jammed enraye/[Adjective]
+jangle (bells) faire retenir[Verb]
+janitor        agent d'entretien[Noun]
+janitor        concierge[Noun]
+jar    bocal[Noun]
+jar    pot[Noun]
+jar    secousse[Noun]
+jargon jargon (m)[Noun]
+jasmine        jasmin[Noun]
+jaundice       jaunisse[Noun]
+jaunt  balade[Noun]
+jaunty désinvolte[Adjective]
+jaunty insouciant(e)[Adjective]
+javelin        javelot[Noun]
+jaw    ma^choir[Noun]
+jaws   ma^choires[Noun]
+jay    geai (m)[Noun]
+jazz   jazz (m)[Noun]
+jazzy  voyant(e)[Adjective]
+jealous        jaloux, jalouse[Adjective]
+jealousy       jalousie[Noun]
+jeer   conspuer[Verb]
+jeer   huer[Verb]
+jelly  gele/e[Noun]
+jellyfish      meduse[Noun]
+jeopardize     compromettre[Verb]
+jeopardize     mettre en danger[Verb]
+jerk   abruti[Noun]
+jerk   bousculer[Verb]
+jerry  boche[Noun]
+jersey (cloth) jersey[Noun]
+jersey pull (m)[Noun]
+jest   plaisanterie (f)[Noun]
+jester bouffon[Noun]
+jester fou[Noun]
+jet    gicleur[Noun]
+jet    re/acteur[Noun]
+jettison       jeter, larguer[Verb]
+jetty  jete/e[Noun]
+jewel  joyau[Noun]
+jeweler        bijoutier[Noun]
+jewelery       bijouterie[Noun]
+jewelry        bijouterie[Noun]
+jewels joyaux[Noun]
+jib    (of crane) flèche (f)[Noun]
+jib    (sail) foc (m)[Noun]
+jiffy  (in a ~) en un clin d'oeil
+jig    gigue (f)[Noun]
+jigsaw (puzzle) puzzle (m)[Noun]
+jihad  lutte, combat (Islam)[Noun]
+jilt   laisser tomber[Verb]
+jingle (bell) tinter[Verb]
+jingle (song) jingle (m), indicatif (m)[Noun]
+jingle (sound) cliquetis (m)[Noun]
+jinx   poisse (f)[Noun]
+jitters        trac[Noun]
+job    boulot (colloq.)[Noun]
+job    emploi (m)[Noun]
+job    turbin (slang)[Noun]
+jobless        au chômage[Adjective]
+jockey jockey (m)[Noun]
+jocular        enjoué(e), jovial(e)[Adjective]
+jocund gai[Adjective]
+jodhpur        jodhpur (m)[Noun]
+jog    faire du jogging[Verb]
+jogging        jogging (m)[Noun]
+join   (re)joindre[Verb]
+join   raccord (m)[Noun]
+joinable       joignable[Adverb]
+joined (re)joint[Adjective]
+joiner menuisier (m)[Noun]
+joinery        menuiserie (f)[Noun]
+joint  (drugs) joint (m)[Noun]
+joint  articulation[Noun]
+joint  jointure[Noun]
+jointly        conjointement[Adverb]
+joke   blague (colloq.)[Noun]
+joke   plaisanterie[Noun]
+joked  plaisanta (pass.simp.,3rd sing[Verb]
+joker  (playing card) joker (m)[Noun]
+jokingly       en plaisantant[Adverb]
+jokingly       pour rire[Adverb]
+jolly  jovial(e), enjoué(e)[Adjective]
+jolt   secousse[Noun]
+jolt   soubresaut (m)[Noun]
+jonquils       jonquilles[Noun]
+jostle bousculer[Verb]
+jot    (~ down) noter[Verb]
+jot    (of truth) grain(m), brin(m)
+journal        (diary) journal (m)[Noun]
+journal        (magazine) revue (f)
+journalism     journalisme (m)
+journalist     journaliste[Noun]
+journalists    journalistes[Noun]
+journey        periple[Noun]
+journey        voyage[Noun]
+jovial jovial(e)[Adjective]
+jovially       jovialement[Adverb]
+joy    joie[Noun]
+joyful joyeux[Adjective]
+joyfully       joyeusement[Adverb]
+joyless        sans joie[Adverb]
+joyously       joyeusement[Adverb]
+jubilant       débordant(e) de joie[Adjective]
+jubilee        jubilé (m)[Noun]
+judge  juge[Noun]
+judge  juger[Verb]
+judged juge/[Adjective]
+judgement      jugement[Noun]
+judicial       judiciaire[Adjective]
+judiciary      magistrature (f)[Noun]
+judo   judo (m)[Noun]
+jug    broc[Noun]
+jug    pichet[Noun]
+jug    pot (m)[Noun]
+juggernaut     poids (m) lourd[Noun]
+juggle jongler[Verb]
+juggler        jongleur (m), jongleusse (f)[Noun]
+jugular        jugulaire[Adjective]
+juice  jus[Noun]
+juiceless      sans jus
+juicier        plus juteux
+juiciest       le plus juteux
+juicy  juteux, juteuse
+jukebox        juke-box (m)[Noun]
+jumble mélange (m)[Noun]
+jumbo  géant(e)[Adjective]
+jump   sauter (inf.)[Verb]
+jumped sauta (pass.simp., 3rd sing.)[Verb]
+jumper robe (f) chasuble[Noun]
+jumpy  nerveux(euse)[Adjective]
+junction       (rail) embranchement (m)[Noun]
+junction       jonction[Noun]
+jungle jungle (f)[Noun]
+junior junior
+juniper        genie\vre[Noun]
+junk   bric-à-brac (m)[Noun]
+junk   camelotte (colloq.)[Noun]
+junk   des ordures[Noun]
+junk   du toc (colloq.)[Noun]
+junkers        casseurs (colloq.)[Noun]
+junkers        chiffonniers[Noun]
+junkie accro (colloq.)[Noun]
+junkie drogué(e)[Noun]
+junkyard       une casse (automobile)[Noun]
+juridic        juridique[Adjective]
+jurisdiction   juridiction[Noun]
+jurist juriste[Noun]
+juror  jure/[Noun]
+jurors jure/s[Noun]
+jury   jury (m)[Noun]
+just   juste
+justice        justice (f)[Noun]
+justified      justifie/(e)[Adjective]
+justify        justifier[Verb]
+justly justement[Adverb]
+jut    (~ out) avancer[Verb]
+juvenile       puéril(e)[Adjective]
+juxtapose      juxtaposer[Verb]
+kale   chou[Noun]
+kaleidescope   kale/idoscope[Noun]
+kaleidoscope   kale/idoscope[Noun]
+kangaroo       kangourou[Noun]
+karat  carat (m)[Noun]
+karate karaté (m)[Noun]
+kayak  kayak (m)[Noun]
+kebab  brochette[Noun]
+keel   la quille (naut.)[Noun]
+keep   garder (inf.)[Verb]
+keeps  toujours[Noun]
+keepsake       souvenir (m)[Noun]
+keg    caisson (liq.)[Noun]
+keg    tonnelet (m), baril (m)[Noun]
+kennel niche (f)[Noun]
+kennel un chenil[Noun]
+kerchief       un foulard[Noun]
+kernel amande (f)[Noun]
+kernel noyau[Noun]
+kernel trognon (fruit)[Noun]
+kerosene       kérosène (m)[Noun]
+ketchup        ketchup (m)[Noun]
+kettle une bouilloire[Noun]
+key    (map) légende
+key    une cle/, or clef[Noun]
+key    une touche (keyboard)[Noun]
+keyboard       un clavier[Noun]
+keyhole        le trou de (la) serrure[Noun]
+keying taper (typewriter) (inf.)[Verb]
+keynote        note (f) dominante[Noun]
+keypad (keyboard) pavé (m) numérique[Noun]
+keypad un clavier (adding machine)[Noun]
+khaki  kaki[Adjective]
+kick   (~ out) vider[Verb]
+kick   donner (inf.) un coup de pied[Verb]
+kickback       un retour de manivelle[Noun]
+kicked frappe/ du pied[Adjective]
+kicker qui donne des coups de pied[Noun]
+kickoff        le depart synchronise/[Noun]
+kicks  s'amuser
+kid    un chevreau, une chevrette[Noun]
+kid    un(e) gosse (colloq.)[Noun]
+kid    un(e) mioche (colloq.)[Noun]
+kiddies        les gamins[Noun]
+kiddies        les gosses[Noun]
+kiddies        les mioches (colloq.)[Noun]
+kidnap enlever (inf.)[Verb]
+kidnap kidnapper[Verb]
+kidnaped       enleve/ (past.part.)[Adjective]
+kidnaper       enlèvement (m)[Noun]
+kidnaper       un ravisseur[Noun]
+kidnapers      les|des ravisseurs[Noun]
+kidnaping      un enle\vement[Noun]
+kidnapped      enleve/[Verb]
+kidnapper      un ravisseur[Noun]
+kidnappers     les|des ravisseurs[Noun]
+kidnapping     un enle\vement[Noun]
+kidnappings    des enle\vements[Noun]
+kidney le rein[Noun]
+kidneys        les|des reins[Noun]
+kidneys        les rognons (cooking)[Noun]
+kids   les|des gamins[Noun]
+kids   les|des gosses[Noun]
+kill   (fig.) mettre fin Ã [Verb]
+kill   tuer[Verb]
+killer meurtrier (m),meutrière (f)[Noun]
+killer un tueur[Noun]
+killers        des tueurs[Noun]
+killing        meutre (m)[Noun]
+killing        une tuerie[Noun]
+killings       des tueries[Noun]
+killjoy        rabat-joie (m)[Noun]
+kiln   four (m)[Noun]
+kiln   un fourneau[Noun]
+kilo   kilo (m)[Noun]
+kilobytes      kilo-octet (m)[Noun]
+kilogram       kilogramme (abbr. kg)[Noun]
+kilohertz      kilo-hertz (m)[Noun]
+kiloliter      un kilolitre (abbr. kl)[Noun]
+kilometer      un kilome\tre (abbr. km)
+kilowatt       kilowatt (m)[Noun]
+kilt   kilt (m)[Noun]
+kin    aparente/ (a\...)[Adjective]
+kind   aimable[Adjective]
+kind   doux (de caracte\re)[Noun]
+kind   gentil(le)[Adjective]
+kindergarten   (le) jardin d'enfants[Noun]
+kindergarten   (une) cre^che pour enfants[Noun]
+kindergarten   (une) garderie (d'enfants)[Noun]
+kindergarten   e/cole maternelle[Noun]
+kindhearted    bon (de caracte\re, de coeur)[Noun]
+kindhearted    tendre de coeur[Adjective]
+kindheartedness        (la) tendresse de coeur[Noun]
+kindle (feeling) susciter[Verb]
+kindle (fire) allumer[Verb]
+kindlessly     froidement[Adverb]
+kindlessly     sans coeur[Adverb]
+kindliness     (la) douceur[Noun]
+kindliness     (la) gentillesse[Noun]
+kindly avec douceur[Adverb]
+kindly bienveillant(e)[Adverb]
+kindly doucement[Adverb]
+kindly gentiment[Adverb]
+kindness       (la) douceur de coeur[Noun]
+kindness       (la) gentillesse[Noun]
+kindred        aparente/[Adjective]
+kindred        semblable, similaire[Adjective]
+kinds  des espe\ces[Noun]
+kinds  des sortes (de...)[Noun]
+king   (le) roi[Noun]
+kingdom        (animals/plants) règne (m)[Noun]
+kingdom        (le) royaume[Noun]
+kingdoms       royaumes[Noun]
+kingfisher     (un) martin pe^cheur (bird)[Noun]
+kingly royal[Adjective]
+kings  (les) rois[Noun]
+kinky  vicieux(ieuse)[Adjective]
+kiosk  kiosque[Noun]
+kipper hereng (m) fumé[Noun]
+kiss   baiser[Verb]
+kiss   baiser[Noun]
+kiss   bisou[Noun]
+kiss   embrasser[Verb]
+kisses baisers[Noun]
+kisses bisous[Noun]
+kit    (set) trousse (f)[Noun]
+kit    (to be assembled) kit (m)[Noun]
+kitchen        cuisine[Noun]
+kitchenette    cuisinette[Noun]
+kitchens       cuisines
+kitchenware    (la) batterie de cuisine[Noun]
+kitchenware    (les) ustensiles de cuisine[Noun]
+kite   (un) cerf-volant[Noun]
+kith   (~ and kin) parents et amis
+kiting jouer avec un cerf-volant[Verb]
+kitten chaton[Noun]
+kittens        chatons[Noun]
+kitty  (shared fund) cagnotte (f)[Noun]
+kiwi   (bird) kiwi (m), aptéryx[Noun]
+kiwi   (fruit) kiwi (m)[Noun]
+kleenex        (un) mouchoir en papier[Noun]
+kleenex        TM, (R), etc. papier-mouchoir[Noun]
+kleptomania    (la) kleptomanie[Noun]
+kleptomaniac   un(e) kleptomane[Noun]
+knack  _ _ _ _ = avoir la main pour..[Noun]
+knack  to have the _ = avoir le chic[Noun]
+knapsack       (un) sac-a\-dos[Noun]
+knead  pe/trir[Verb]
+kneadable      pe/trissable[Adjective]
+kneader        pe/trisseur[Noun]
+knee   le genou[Noun]
+kneecap        la rotule[Noun]
+kneel  mettre Ã  genoux[Verb]
+kneel  s'agenouiller (inf.reflx.)[Verb]
+kneeling       a\ genoux[Adverb]
+kneeling       s'agenouillant[Verb]
+kneepad        (un) prote\ge-genou[Noun]
+knelt  s'agenouilla (pass.simp.)[Verb]
+knelt  se mis(e) a\ genoux (pass.simp[Verb]
+knickers       pantalon de golf (m)[Noun]
+knickknack     (un) bibelot[Noun]
+knickknack     (une) babiole[Noun]
+knife  (un) canif[Noun]
+knife  (un) couteau[Noun]
+knifes des couteaux[Noun]
+knifing        une blessure au couteau[Noun]
+knight (chess) cavalier (m)[Noun]
+knight (un) chevalier[Noun]
+knighted       e^tre sacre/ chevalier[Adjective]
+knighthood     la chevalerie[Noun]
+knightly       chevalier[Adjective]
+knights        des chevaliers[Noun]
+knit   (bones) se souder[Verb]
+knit   froncer les sourcils[Verb]
+knit   tricotter (inf.)[Verb]
+knitted        tricotte/ (past.part.)[Adjective]
+knitting       le tricot[Noun]
+knitwear       le tricot[Noun]
+knives des couteaux[Noun]
+knob   (la) poigne/e[Noun]
+knob   (un) bouton (de commande)[Noun]
+knobby noueux, noueuse[Adjective]
+knobs  (les) boutons (de commande)[Noun]
+knock  frapper (inf.)[Verb]
+knock  tapoter[Verb]
+knockdown      démolir[Verb]
+knockout       knock-out (m)[Noun]
+knot   (un) noeud[Noun]
+knots  des noeuds[Noun]
+knotted        noue/ (past.part.)[Adjective]
+knotty Ã©pineux(euse)[Adjective]
+knotty noueux[Adjective]
+know   savoir (inf.)[Verb]
+knower celui|celle qui a le savoir[Noun]
+knowhow        le savoir-faire[Noun]
+knowhow        technique (f)[Noun]
+knowing        entendu(e)[Adjective]
+knowingly      en connaissance de cause[Adverb]
+knowingly      sciemment[Adverb]
+knowledge      la connaissance[Noun]
+knowledge      le savoir[Noun]
+knowledgeable  bien informé(e)[Adjective]
+known  connu (past.part.)[Verb]
+knows  (il|elle) sait[Verb]
+knuckle        (meat) jarret (m)
+knuckle        (une) phalange[Noun]
+knucklebone    (une) phalange[Noun]
+knuckles       (un) poing ame/ricain[Noun]
+knuckles       les phalanges[Noun]
+koala  koala (m)[Noun]
+kosher cache\re[Adjective]
+kosher kasher[Adjective]
+kraut  (la) choucroute[Noun]
+kraut  (un) boche (slang)[Noun]
+krauts les chleus (slang.)[Noun]
+kudzu  lierre du Japon[Noun]
+lab    labo[Noun]
+labor  travail (m)[Noun]
+laborer        l'ouevrier[Noun]
+laborer        l'ouvrier[Noun]
+laborers       les ouevriers[Noun]
+laborers       les ouvriers[Noun]
+laborious      laborieux (m), laborieuse (f)[Noun]
+labyrinth      labyrinthe (m)[Noun]
+lace   dentelle (f)[Noun]
+laceration     lace/ration (f)[Noun]
+lacerations    lace/rations (f)[Noun]
+lack   manque[Noun]
+lackadaisical  nonchalant[Adjective]
+lackey laquais[Noun]
+lacking        simplet[Adjective]
+lackluster     terne[Adjective]
+laconic        laconique[Adjective]
+laconically    laconiquement[Adjective]
+lacquer        (for wood) vernis (m)[Noun]
+lacquer        laque[Noun]
+lad    garcon[Noun]
+ladies Mesdames[Noun]
+lady   dame[Noun]
+ladybird       coccinelle[Noun]
+ladybug        coccinelle[Noun]
+lake   lac[Noun]
+lakes  lacs[Noun]
+lamb   veau[Noun]
+lambs  veaux[Noun]
+laminated      laminé[Verb]
+laminates      lamine[Verb]
+lamp   lampe[Noun]
+language       langue[Noun]
+laugh  rire[Verb]
+leather        cuir[Noun]
+leave  laisser[Verb]
+lectern        lutrin[Noun]
+lecture        confe/rence[Noun]
+lecturer       confe/rencier[Noun]
+ledge  rebord[Noun]
+ledger registre[Noun]
+lee    co^te/[Noun]
+leg    jambe[Noun]
+legal  legal[Adjective]
+legality       legalite[Noun]
+legalize       legaliser[Noun]
+legally        legalement[Adverb]
+legate leguer[Verb]
+legation       legation[Noun]
+legend legende[Noun]
+legendary      lengendaire[Adjective]
+legion legion[Verb]
+letter additive[]
+letter ethnic[]
+letter neighbor[]
+like   aimer[Verb]
+live   vivre[Verb]
+love   aime
+love   amour[Noun]
+lover  amant[Noun]
+luck   chance[Noun]
+lunch  le de/jeuner[Noun]
+ma     maman[Noun]
+ma     Mère[Noun]
+ma'am  M'dame[Noun]
+ma'am  madame[Noun]
+ma'am  mademoiselle[Noun]
+macabre        lugubre[Adjective]
+macabre        macabre[Adjective]
+macabrely      macabrement[Adverb]
+macadam        bitume[Noun]
+macadam        macadam[Noun]
+macadamize     goudronner[Verb]
+macadamize     macadamiser[Verb]
+macadamized    goudronné[Verb]
+macadamized    macadamise/[Adjective]
+macadamizes    goudronnes[Verb]
+macadamizes    macadamise[Verb]
+macadamizing   goudronnant[Verb]
+macaque        macaque[Noun]
+macaque        macaque[Noun]
+macaroni       macaroni[Noun]
+macaronies     macaronis[Noun]
+macaroon       macaron[Noun]
+macaw  l'ara[Noun]
+mace   sceptre[Noun]
+macerate       mace'rer[Verb]
+macerate       maçérer[Verb]
+macerated      macere'[Adjective]
+maceration     mace'ration[Noun]
+macerations    mace'rations[Noun]
+maces  masse[Noun]
+machete        machette[Noun]
+machination    machination[Noun]
+machine        machine[Noun]
+machined       machine/[Adjective]
+machineries    machinerie
+machinery      machinerie[Noun]
+machines       machines[Noun]
+machinist      machiniste[Noun]
+machinists     machinistes[Noun]
+machismo       machisme[Noun]
+macho  macho[Adjective]
+macrocephalic  macroce'phale[Adjective]
+macrocosm      macrocosme[Noun]
+macroeconomics macroeconomie[Noun]
+macroevolution macroe'volution[Noun]
+macroevolutionary      macroe'volutionnaire[Adjective]
+macroinstruction       macroinstruction
+macromolecular macromole'culaire[Adjective]
+macromolecule  macromole'cule[Noun]
+macromolecules macromole'cules[Noun]
+macropathological      macropathologique[Adjective]
+macropathology macropathologie[Noun]
+macrophage     macrophage[Noun]
+macrophages    macrophages[Noun]
+macrophagic    macrophage[Adjective]
+macroprocessor macroprocesseur[Noun]
+macroscopic    macroscopic[Adjective]
+macrosimulation        macrosimulation[Noun]
+macrostructure macrostructure[Noun]
+maculate       maculer[Verb]
+maculated      macule'[Adjective]
+maculates      macule[Verb]
+maculation     maculation[Noun]
+maculations    maculations[Noun]
+mad    fache'[Adjective]
+mad    fou, folle[Adjective]
+madam  madame[Noun]
+madams mesdames[Noun]
+maddened       rendu fou[Adjective]
+made   a fait[Verb]
+made   j'adore[Verb]
+mademoiselle   mademoiselle[Noun]
+mademoiselles  mesdemoiselles[Noun]
+maestro        maestro[Noun]
+mafioso        mafieux[Noun]
+magazine       magazine[Noun]
+magic  magique[Adjective]
+magician       magicien[Noun]
+magicians      magiciens[Noun]
+magistral      magistral[Adjective]
+magistrally    magistralement[Adverb]
+magistrature   magistrature[Noun]
+magma  magma[Noun]
+me     moi[Pronoun]
+mead   le hydromel[Noun]
+meadow le pre/[Noun]
+meadow pre/[Noun]
+meadowland     les prairies[Noun]
+meadows        pre/s[Noun]
+meager maigre[Adjective]
+meagerly       maigrement[Adverb]
+meagre maigre[Adjective]
+meal   repas[Noun]
+meals  repas[Noun]
+mealtime       heure du repas[Noun]
+mean   moyenne[Noun]
+meander        me/andre[Noun]
+meaningless    insense/[Adjective]
+meanings       significations[Noun]
+means  moyen[Noun]
+meanwhile      entretemps[Adverb]
+measurable     mesurable[Adjective]
+meat   viande[Noun]
+meatball       boulette de viande[Noun]
+meatballs      boulettes de viande[Noun]
+mechanical     me/canique[Adjective]
+mechanician    me/canicien[Noun]
+mechanism      me/canisme[Noun]
+mechanisms     me/canismes[Noun]
+medal  me/daille[Noun]
+medallion      me/daillon[Noun]
+medallions     me/daillons[Noun]
+mediatrice     me/diatrice[Noun]
+mediatrix      me/diatrice[Noun]
+medic  me/decin[Noun]
+medical        me/dical[Adjective]
+medically      me/dicalement[Conjunction]
+medicament     me/dicament[Noun]
+medicaments    me/dicaments[Noun]
+medicinal      me/dicinal[Adjective]
+medicine       me/decine[Noun]
+medicines      me/decines[Noun]
+medico medico[Adjective]
+medicolegal    me/dicole/gal[Adjective]
+medics me/decins[Noun]
+medieval       me/die/val[Adjective]
+medievalist    me/die/valiste[Noun]
+medievalists   me/die/valistes[Noun]
+mediocre       me/diocre[Adjective]
+mediocrities   me/diocrite/s[Noun]
+mediocrity     me/diocrite/[Noun]
+meditate       me/diter[Verb]
+meditates      me/dite[Verb]
+meditation     me/ditation[Noun]
+meditations    me/ditations[Noun]
+meditative     me/ditatif[Adjective]
+meditatively   d'un air me/ditatif[Adjective]
+medium me/dium[Noun]
+medlar ne\fle[Noun]
+medley me/lange[Noun]
+medleys        me/langes[Noun]
+medulla        me/dulle[Noun]
+medusae        me/duses[Noun]
+meek   doux[Adjective]
+meekly avec soumission[Adjective]
+meekness       soumission[Noun]
+meerschaum     pipe en e/cume de mer[Noun]
+megabyte       me/ga-octet[Noun]
+megabytes      me/ga-octets[Noun]
+megacycle      me/gacycle[Noun]
+megahertz      me/gahertz[Noun]
+megalith       me/galithe[Noun]
+megalithic     me/galitic[Adjective]
+megalomania    me/galomanie[Noun]
+megalomaniac   me/galomane[Noun]
+megalomaniacal me/galomane[Adjective]
+megaphone      me/gaphone[Noun]
+melancholia    me/lancolie[Noun]
+melancholic    me/lancolique[Adjective]
+melange        me/lange[Noun]
+melodic        me/lodique[Adjective]
+melodies       me/lodies[Noun]
+melodious      me/lodieux[Adjective]
+melodrama      me/lodrame[Noun]
+melodramas     me/lodrames[Noun]
+melodramatic   me/lodramatique[Adjective]
+melody me/lodie[Noun]
+melon  melon[Noun]
+melons melons[Noun]
+melted fondu[Pronoun]
+member membre[Noun]
+members        membres[Noun]
+membrane       membrane[Noun]
+membranes      membranes[Noun]
+membranous     membraneux[Adjective]
+memoir me/moire[Noun]
+memoirs        me/moires[Noun]
+memorable      me/morable[Adjective]
+memories       souvenirs[Noun]
+memorize       me/moriser[Verb]
+memorized      me/morise/[Pronoun]
+memory me/moire, souvenir[Noun]
+men    hommes[Noun]
+menace menace[Noun]
+menaced        menace/[Adjective]
+menagerie      me/nagerie[Noun]
+menageries     me/nageries[Noun]
+menhir menhir[Noun]
+meningitis     me/ningite[Noun]
+meniscus       me/nisque[Noun]
+menopause      me/nopause[Noun]
+menstrual      menstruel[Adjective]
+menstruation   menstruation[Noun]
+menstruations  menstruations[Noun]
+mental mental[Adjective]
+mentality      mentalite/[Noun]
+menthol        menthol[Noun]
+mention        mentionner[Verb]
+menu   menu[Noun]
+meow   miauler[Verb]
+meowing        miauleur[Adjective]
+meows  miaule[Verb]
+mephitic       me/phitique[Adjective]
+mercantile     mercantile[Adjective]
+mercantilism   mercantilisme[Noun]
+mercenaries    mercenaires[Noun]
+mercenary      mercenaire[Noun]
+merchant       marchand[Noun]
+merchants      marchands[Noun]
+mercury        mercure[Noun]
+mercy  pitie/[Noun]
+meridian       me/ridien[Noun]
+meridians      me/ridiens[Noun]
+meridional     me/ridional[Adjective]
+merino me/rino[Noun]
+merit  me/rite[Noun]
+meritocracy    me/ritocratie[Noun]
+merits me/rites[Noun]
+mermaid        sire\ne[Noun]
+mermaids       sire\nes[Noun]
+merry  joyeux[Adjective]
+message        message[Noun]
+messages       messages[Noun]
+messiahs       messie[Noun]
+messianic      messianique[Adjective]
+moan   gémir[Verb]
+moaned gémit[Verb]
+moaning        gémissant[Verb]
+moans  gémissements
+moat   fossé[Noun]
+moats  fosséa[Noun]
+mob    foule[Noun]
+mock   ridiculiser[Verb]
+mocked ridiculisé[Verb]
+mockery        moquerie[Noun]
+modal  modal[Adjective]
+moon   lune[Noun]
+moonlight      clair de lune
+moons  lunes
+moose  orignal
+naive  naif, naive[Adjective]
+naively        naivement[Adverb]
+naked  nu[Noun]
+name   prenom(persons), nom (things)[Noun]
+named  nomme[Adjective]
+nameless       sans nom[Adjective]
+namely nomement [Adverb]
+namely nommement[Adverb]
+names  prenoms, noms (see name)[Noun]
+national       national/e[Adjective]
+nationalism    nationalisme[Noun]
+nationalist    nationaliste[Adjective]
+native habitant/e du pays[Noun]
+natural        naturel (le)[Adjective]
+naturalize     naturaliser[Verb]
+naturally      naturellement[Adverb]
+neap   mortes-eaux[Noun]
+near   proche[Adjective]
+nearby près[Adverb]
+nearer plus proche[Adjective]
+neglect        abandonner[Verb]
+neighbor       voisin[Noun]
+neighbors      voisins[Noun]
+network        réseau
+networked      réseauté
+networks       réseaux
+nine   neuf[Adjective]
+nineteen       dix-neuf[Adverb]
+nineteenth     dix-neuvie\me[Adjective]
+nineties       les anne/es quatre-vingt-dix[Noun]
+ninetieth      quatre-vingt-dixie\me[Adjective]
+ninety quatre-vingt-dix[Adverb]
+ninetyfold     quatre-vingt-dix fois[Adverb]
+ninth  neuvie\me[Adjective]
+niobium        niobium (m)[Noun]
+nip    te/ton (m)[Noun]
+nipple te/ton[Noun]
+nipples        te/tons[Noun]
+nips   te/tons (m)[Noun]
+nirvana        nirvana[Noun]
+nitrate        nitrate[Noun]
+nitrated       nitrate/[Noun]
+nitrates       nitrates[Noun]
+nitrating      nitratant[Adverb]
+nitration      nitratation[Noun]
+nitrations     nitratations[Noun]
+nitric nitrique[Adjective]
+nitride        nitrate (m)[Noun]
+nitrogen       azote[Noun]
+nitroglycerin  nitroglyce/rine[Noun]
+nitroglycerine nitroglyce/rine[Noun]
+noble  noble[Noun]
+nobleman       noble[Noun]
+noblemen       nobles[Noun]
+nobleness      noblesse[Noun]
+nobody personne[Pronoun]
+noctambulism   noctambulisme[Noun]
+noctambulist   noctambule[Noun]
+nocturn        noctune
+nocturnally    de nuit[Noun]
+now    maintenant[Adverb]
+nowadays       de nos jours, aujourd'hui[Adverb]
+noway  pas question, pas du tout[Adverb]
+noway  pas question, pas du tout[Adverb]
+oaf    nigaud[Noun]
+oafish stupide[Adjective]
+oafishness     sottise[Noun]
+oak    che^ne[Noun]
+oar    rame[Noun]
+oarsman        rameur[Noun]
+oasis  oasis[Noun]
+oat    avoine[Noun]
+oath   serment[Noun]
+oatmeal        farine d'avoine[Noun]
+obdurate       inve/te/re/[Adjective]
+obedience      obe/issance[Noun]
+obedient       soumis[Adjective]
+obelisk        obe/lisque[Noun]
+obese  obe\se[Adjective]
+obesity        obe/site/[Noun]
+ocean  ocean[Noun]
+one    un[Noun]
+orange orange[Noun]
+oranges        oranges[Noun]
+orbit  orbite[Noun]
+orbital        orbital[Adjective]
+orbits orbites[Noun]
+orchestra      orchestre[Noun]
+orchestral     orchestral[Adjective]
+orchestras     orchestres[Noun]
+orchestrated   orchestré[Adjective]
+order  commande[Noun]
+ordered        ordonné[Adjective]
+organism       organisme[Noun]
+organisms      organismes[Noun]
+organist       organiste[Noun]
+organists      organistes[Noun]
+organization   organisation[Noun]
+organizations  organisations[Noun]
+organize       organiser[Verb]
+organized      organisé[Adjective]
+organs organes[Noun]
+orgasm orgasme[Noun]
+orgasms        orgasmes[Noun]
+orgies orgies[Noun]
+orgy   orgie[Noun]
+orient orient[Noun]
+orientable     orientable[Adjective]
+oriental       oriental[Adjective]
+orientation    orientation[Noun]
+orientations   orientations[Noun]
+oriented       orienté[Adjective]
+orients        orients[Noun]
+orifice        orifice[Noun]
+orifices       orifices[Noun]
+orificial      orifique[Adjective]
+origin origine[Noun]
+original       original[Adjective]
+originality    originalité[Adjective]
+originally     originalement[Adverb]
+originals      originaux[Adjective]
+origins        origines[Noun]
+ornamental     ornemental[Adjective]
+ornithology    ornithologie[Noun]
+orthodox       orthodoxe[Adjective]
+orthodoxes     orthodoxes[Adjective]
+orthogonal     orthogonal[Adjective]
+pace   rhytme[Noun]
+pace   vitesse[Noun]
+pacemaker      stimulateur cardiaque (m), pacemaker (m)[Noun]
+pachyderm      pachyde\rme[Noun]
+pacific        pacifique[Noun]
+pacifically    pacifiquement[Adverb]
+pacification   pacification(f)[Noun]
+pacifications  pacificateur / -trice [Noun]
+pacificist     pacifiste[Noun]
+pacifier       tétine (f), sucette (f)
+pacifism       pacifisme[Noun]
+pacifist       pacifiste[Noun]
+pacify apaiser[Verb]
+pacify pacifier[Verb]
+package        2)paquet(m);3)ballot(m)[Noun]
+package        emballage[Noun]
+packaged       emballeE[Adverb]
+packaged       paquet (m)[Noun]
+packed (~ with) bourré(e) de
+packet 1) paquet (m) ;2)ballot(m)[Noun]
+packing        emballage (m)[Noun]
+pact   pacte, contrat[Noun]
+pacts  pcates, contrats[Noun]
+pad    coussinet, tampon[Noun]
+padding        rembourrage, remplissage[Noun]
+paddle pagaie, palette[Noun]
+paddock        enclos, paddock[Noun]
+padlock        cadenas[Noun]
+padlock        cadenasser[Verb]
+padrone        patron /nne[Noun]
+paella paella[Noun]
+pagan  pai.en/i.enne)
+pagan  payen /nne[Noun]
+pagans pa&iumlen(ne)s[Noun]
+pageant        spectacle[Noun]
+pageantry      apparat[Noun]
+paid   payé(e)[Adjective]
+pail   seau[Noun]
+pain   douleur[Noun]
+pained peiné(e)[Adjective]
+painful        douleureux[Adjective]
+painful        pénible[Adjective]
+painfully      douloureusement[Adverb]
+painstaking    assidu(e)[Adjective]
+paint  peindre[Verb]
+paint  peinture[Noun]
+paintbrush     pinceau[Noun]
+painter        peintre[Noun]
+painters       peintre[Noun]
+painting       peinture[Noun]
+paints couleurs[Noun]
+pair   couple[Noun]
+pajamas        pyjama[Noun]
+pal    copain (m)[Noun]
+pal    copine (f)
+palace palais[Noun]
+palatable      agréable au goût[Adjective]
+palaver        palabres (f)[Noun]
+pale   pâle[Adjective]
+palette        palette (f)[Noun]
+pall   voile (m)[Noun]
+pallet palette (f)[Noun]
+pallette       palette (f)[Noun]
+pallor pâleur (f)[Noun]
+palm   (~ tree) palmier (m)[Noun]
+palm   paume (f)[Noun]
+palpable       Ã©vident(e)[Adjective]
+palpable       manifeste [Adjective]
+paltry dérisoire[Adjective]
+pamper choyer, dorloter[Verb]
+pamphlet       brochure (f)[Noun]
+pan    casserole (f)[Noun]
+panacea        panacée (f)[Noun]
+panama Panama (m)[Noun]
+pancake        crêpe (f)[Noun]
+panda  panda (m)[Noun]
+pandemonium    tohu-bohu (m)[Noun]
+pane   vitre (f), carreau (m)[Noun]
+panel  invités (m)[Noun]
+paneling       lambris (m)[Noun]
+panelling      lambris (m)[Noun]
+pang   tiraillement (m)[Noun]
+panic  panique (f)[Noun]
+panic  paniquer[Verb]
+panicky        paniqué(e)[Adjective]
+panorama       panorama (m)[Noun]
+pansy  pensée(f)[Noun]
+pant   haleter[Verb]
+panther        panthère (f)[Noun]
+panties        culotte (f)[Noun]
+pantry garde-manger (m)[Noun]
+pants  pantalon (m)[Noun]
+papa   papa (m)[Noun]
+paper  papier (m)[Noun]
+paperback      livre de poche (m)[Noun]
+parameter      paramètre[Noun]
+passer passeur[Noun]
+passion        passion[Noun]
+passionately   passionne/ment[Adverb]
+passive        passif[Adjective]
+passivity      passivite/[Noun]
+password       mot de passe[Noun]
+passwords      mots de passe[Noun]
+past   passe/[Noun]
+pasta  pâtes alimentaires[Noun]
+peat   tourbe[Noun]
+pectorals      pectoraux[Noun]
+peculiar       important
+penitence      pe/nitence[Noun]
+penitences     pe/nitences[Noun]
+penitency      pe/nitence[Noun]
+penitent       pe/nitent[Noun]
+pentadactyl    pentadactyle[Adjective]
+pentadactylism pentadactylisme[Noun]
+pi     pi[Noun]
+pianist        pianiste[Noun]
+pianistic      pianistique[Adjective]
+piano  piano[Noun]
+picture        image[Noun]
+pictures       images[Noun]
+pie    tarte[Noun]
+pies   tartes[Noun]
+pig    cochon[Noun]
+pigeonhole     pigeonnier[Noun]
+pigment        pigment[Noun]
+pigmentation   pigmentation[Noun]
+pigments       pigments[Noun]
+pigs   cochons[Noun]
+pilot  pilote[Noun]
+pilots pilotes[Noun]
+pilule pilule[Noun]
+pine   pin[Noun]
+pineapple      ananas[Noun]
+pineapples     ananas[Noun]
+pines  pins[Noun]
+pink   rose[Noun]
+pocket poche[Noun]
+pocketbook     livre de poche[Noun]
+pocketbooks    livres de poche[Noun]
+pockets        poches[Noun]
+podium podium[Noun]
+pogrom pogrom[Noun]
+pogroms        pogroms[Noun]
+pointer        pointeur[Noun]
+pointers       pointeurs[Noun]
+pointillism    pointillisme[Noun]
+pointillist    pointilliste[Noun]
+pointilliste   pointilliste[Noun]
+pointillistic  pointilliste[Noun]
+poison poison[Noun]
+poisonous      poison[Adjective]
+poisonousness  toxicite/[Noun]
+poisons        poisons[Noun]
+polar  polaire[Adjective]
+polarities     polarite/s[Noun]
+polarity       polarity[Noun]
+polarize       polariser[Verb]
+polarized      polarise/[Adjective]
+polemical      pole/mique[Adjective]
+polemically    de fac,on pole/mique[Adjective]
+polemically    de manie\re pole/mique[Adverb]
+polemicize     pole/miquer
+police police[Noun]
+policeman      agent de police[Noun]
+policeman      agent[Noun]
+policeman      policier[Noun]
+policemen      agents de police[Noun]
+policemen      agents[Noun]
+policemen      policiers[Noun]
+policewoman    contractuelle[Noun]
+policewomen    contractuelles[Noun]
+policy politique[Noun]
+polish polonais[Adjective]
+polish Polonais[Noun]
+polite poli[Adjective]
+politely       poliment[Adverb]
+politeness     politesse[Noun]
+political      politique[Adjective]
+politically    politiquement[Adverb]
+politician     politicien[Noun]
+politicians    politiciens[Noun]
+politics       politique[Noun]
+polka  polka[Noun]
+pollutant      polluant[Noun]
+pollute        polluer[Verb]
+polluted       pollue/[Adjective]
+polluter       pollueur[Noun]
+pollution      pollution[Noun]
+polonium       polonium[Noun]
+poltergeist    poltergeist[Noun]
+polyandrous    polyandre[Adjective]
+polyandry      polyandrie[Noun]
+pour   french[Noun]
+pout   moue[Noun]
+poverty        pauvrete/[Noun]
+powder poudre[Noun]
+powdery        poudreux[Adjective]
+power  puissance[Noun]
+powerful       puissant[Adjective]
+powerless      impuissant[Adjective]
+powwow assemble/e[Noun]
+practicability possibilite/[Noun]
+practicable    re/alisable[Adjective]
+practical      pratique[Adjective]
+pray   prier[Verb]
+prayer prie\re[Noun]
+prayers        prie\res[Noun]
+praying        en prie\res[Adjective]
+praying        prie\re[Noun]
+preach pre^cher[Verb]
+preach prononcer[Verb]
+preacher       pasteur[Noun]
+preacher       pre/dicateur[Noun]
+preachers      pasteurs[Noun]
+preachers      pre/dicateurs[Noun]
+preaches       pre^che[Verb]
+preaches       prononce[Verb]
+preachify      faire la morale[Verb]
+preaching      pre/dication[Noun]
+preaching      pre^cheur[Adjective]
+preaching      sermons[Noun]
+preachy        pre^cheur[Adjective]
+preachy        sermonneur[Adjective]
+preamplifier   pre/amplificateur[Noun]
+preamplifiers  pre/amplificateurs[Noun]
+prearrange     arranger au pre/alable[Verb]
+prearrange     arranger d'avance[Verb]
+prince prince[Noun]
+princedom      principaute/
+princely       princier[Adjective]
+princes        princes[Verb]
+princess       princesse[Noun]
+principal      principal[Noun]
+principal      directeur[Noun]
+principalities principaute/s[Noun]
+principality   principaute/
+principally    principalement
+principally    surtout
+principals     directeurs
+principle      principe[Noun]
+principles     principes
+print  empreinte[Noun]
+print  impression[Noun]
+print  marque
+printable      imprimable[Adjective]
+printed        imprime/[Adjective]
+printer        imprimeur[Noun]
+printer        imprimante[Noun]
+priorities     priorite/
+priorities     priorite/s
+priority       priorite/
+prove  prouver[Verb]
+pulse  impulsion[Noun]
+pulverizable   pulverisable[Adjective]
+pulverizables  pulverisables[Adjective]
+pulverization  pulverisation[Noun]
+pulverize      pulveriser[Verb]
+pulverized     pulvérisé[Verb]
+pulverizer     pulverisateur[Noun]
+pulverizers    pulvérisateurs[Noun]
+pulverizes     pulvérises[Verb]
+pulverizing    pulve/risant[Verb]
+puma   puma[Noun]
+pump   pomper[Verb]
+push   pousser[Verb]
+pushchair      chaise roulante[Noun]
+pushing        poussé[Verb]
+put    mettre[Verb]
+putdown        poser[Verb]
+putout Ã©teindre[Verb]
+putrefaction   putréfaction[Noun]
+quail  caille[Noun]
+quails cailles[Noun]
+quake  trembler[Verb]
+quality        qualite/[Noun]
+qualm  scrupule[Noun]
+qualms scrupules[Noun]
+quantity       quantite/
+quarrel        se disputer[Verb]
+quarry carri\ere[Noun]
+quarter        quartier[Noun]
+quarterdeck    plage arri\ere[Noun]
+quarterfinal   quart de finale[Noun]
+queen  reine[Noun]
+queer  bizarre[Adjective]
+quell  re/primer[Verb]
+quench se de/salte/rer
+querulous      ronchonneur[Adjective]
+query  question[Noun]
+quest  que^te[Noun]
+question       question[Noun]
+queue  queue[Noun]
+quibble        chicaner[Verb]
+quick  rapide[Adjective]
+quicklime      chaux vive[Noun]
+quickly        rapidement[Adverb]
+quicksand      sables mouvants[Noun]
+quicksilver    vif-argent[Noun]
+quiet  tranquille[Adjective]
+quieten        calmer[Verb]
+quietly        doucement[Adverb]
+quill  plume d'oie[Noun]
+quilt  e/dredon[Noun]
+quirk  bizarrerie[Noun]
+quit   se rendre[Verb]
+quite  assez[Adjective]
+quota  quota[Noun]
+quotation      citation[Noun]
+quote  citer[Verb]
+r      r[Noun]
+rabbet feuillure[Noun]
+rabbi  rabbin
+rabbinic       rabbinique[Adjective]
+rabbit lapin[Noun]
+rabbits        lapins[Noun]
+rabble cohue[Noun]
+rabid  enrage/[Adjective]
+rabies rage
+raccoon        raton-laveur
+race   course[Noun]
+racehorse      cheval de course
+racemic        rece/mique[Adjective]
+racer  coureur
+races  courses[Noun]
+rachis rachis[Noun]
+rachitic       rachitique[Adjective]
+rachitis       rachitisme[Noun]
+racial racial[Adjective]
+racialism      racisme[Noun]
+racialist      raciste[Noun]
+racialistic    raciste[Adjective]
+racing de course
+racism racisme[Noun]
+racist raciste[Noun]
+rack   e/tag\ere[Noun]
+racket raquette[Noun]
+racket tumulte[Noun]
+radar  radar[Noun]
+radars radars[Noun]
+radio  radio[Noun]
+read   lire[Verb]
+readability    lisibilite/[Noun]
+readable       lisible[Adjective]
+reader lecteur[Noun]
+readers        lecteurs[Noun]
+readership     lecteurs[Noun]
+readership     lectorat[Noun]
+readily        de bonne gra^ce[Adverb]
+readily        facilement[Adverb]
+readily        volontiers[Adverb]
+readiness      empressement[Noun]
+readiness      facilite/[Noun]
+reading        interpre/tation[Noun]
+reading        lecture[Noun]
+reading        releve/[Noun]
+readings       interpre/tations[Noun]
+readings       lectures[Noun]
+readjust       rajuster[Verb]
+readjust       re/ajuster[Verb]
+readjusts      rajuste[Verb]
+readjusts      re/ajuste[Verb]
+readout        affichage[Noun]
+readout        d'affichage[Adjective]
+readouts       affichages[Noun]
+reads  lit[Verb]
+ready  dispose/[Adjective]
+ready  pre^t[Adjective]
+ready  prompt[Adjective]
+reaffirm       affirmer de nouveau[Verb]
+reaffirm       re/affirmer[Verb]
+reaffirms      affirme de nouveau[Verb]
+reaffirms      re/affirme[Verb]
+reagent        re/actif[Noun]
+real   naturel[Adjective]
+real   ve/ritable[Adjective]
+real   vrai[Adjective]
+realisable     re/alisable[Adjective]
+realism        re/alisme[Noun]
+realist        re/aliste[Noun]
+realistic      plein de re/alisme[Adjective]
+realistic      re/aliste[Adjective]
+realistically  avec re/alisme[Adverb]
+reality        re/alite/[Noun]
+realize        re/aliser[Verb]
+really vraiment[Adverb]
+reporter       le reporter[Noun]
+represent      repre/senter[Verb]
+request        demande[Noun]
+request        exiger[Verb]
+request        reque^te[Noun]
+road   rue[Noun]
+roads  rues
+roadwork       chantier[Noun]
+robber voleur[Noun]
+room   chambre
+rotting        decay[Verb]
+sabbat un sabbat[Noun]
+sabbath        sabbat[Noun]
+sabbatic       sabatique[Noun]
+sabbatical     sabbatique[Adjective]
+saber  sabre[Noun]
+sabin  nom de personne qui a decouvert le vaccine contre poliomyltie[Noun]
+sable  martre[Noun]
+sabot  sabot[Noun]
+sabotage       sabotage[Noun]
+sabotaged      saboté[Verb]
+sabotages      sabotages[Noun]
+saboteur       saboteur[Noun]
+sabra  citoyen du pays Israel, personne ne en Israel[Noun]
+sabras citoyens du pays Israel, personnese nes en Israel[Noun]
+saccade        une saccade[Noun]
+saccharin      saccharine[Verb]
+saccharine     saccharin[Noun]
+saccharose     saccharose[Noun]
+sacerdotal     appartient a une chose religieuse[Adjective]
+sacerdotally   une acte faite en manière sacrée[Adverb]
+sachet un sachet[Noun]
+sack   sac[Noun]
+sack   virer[Verb]
+sackcloth      une vêtement de deuil[Noun]
+sacked vire/[Adjective]
+sackful        une mesure "plein d'un sac"[Adjective]
+sacks  piller[Verb]
+sacrament      sacrament[Noun]
+sacramental    sacremental[Adjective]
+sacraments     sacrements[Noun]
+sacre  sacre[Noun]
+sacred sacre/[Adjective]
+sacrifice      sacrifice[Noun]
+sacrificed     sacrifier[Verb]
+sacrifices     sacrifices[Noun]
+sacrilege      sacrile\ge[Noun]
+sad    malheureux[Adjective]
+sad    triste[Adjective]
+sadden attrister[Verb]
+sadder plus triste[Adjective]
+saddest        plus triste[Adjective]
+saddle selle[Noun]
+saddlebag      une sacoche[Noun]
+saddlebags     des sacoches
+saddlebow      un arçon
+saddlecloth    une housse ( de cheval)[Noun]
+saddled        sellé[Verb]
+saddleless     sans selle
+saddler        un sellier[Noun]
+saddlery       une sellerie[Noun]
+saddles         une selle
+saddletree     un bois de selle[Noun]
+saddling       sellant[Verb]
+sadism sadisme[Noun]
+sadist sadiste[Noun]
+sadistic       sadique[Adjective]
+sadistically   sadiquement[Adverb]
+sadists        sadistes[Noun]
+sadly  tristement[Adverb]
+sadness        tristesse[Noun]
+safari un voyage, en particulier en Afrique[Noun]
+safe   coffre-fort[Noun]
+safecracker    une personne qui ouvre une caisse illégalement[Noun]
+safecracking   l'acte d'ouvrir une caise illégalement[Noun]
+safeguard      une sauvegarde[Noun]
+safeguarded    sauvegardé[Verb]
+safeguards     garde fous[Noun]
+safer  pplus sauf[Adjective]
+safes  les caisses[Noun]
+safest le plus sauf[Adjective]
+safety le sûreté[Noun]
+safflower      le carthame[Noun]
+saffron        le safran[Noun]
+sag    plier, ployer[Verb]
+saga   une saga[Noun]
+sagacious      prudent[Adjective]
+sagaciously    prudemment[Adverb]
+sagaciousness  la sagacité[Noun]
+sagacity       la sagacité[Noun]
+sage   le sage[Noun]
+sagely sagement[Adjective]
+sago   le sagou[Noun]
+saguaro        une type de cactus[Noun]
+sahib  une forme d'addresser pour un homme des Indes[Noun]
+said   dit[Verb]
+sail   naviguer[Verb]
+sail   voile[Noun]
+sailable       navigable[Adjective]
+sailboat       un bateau  Ã  voiles[Noun]
+sailboater     un marin des bateua Ã  voiles[Noun]
+sailcloth      la toile Ã  voiles[Noun]
+sailor marin[Noun]
+sailors        les marins[Noun]
+sails  les voiles[Noun]
+sainfoin       le sainfoin ( bot.)[Noun]
+saint  saint(e)[Noun]
+sainted        sacré[Adjective]
+sainthood      la sainteté[Noun]
+saints saint(e)s[Noun]
+saith  dit ( vieux anglais)[Verb]
+sake   le vin du riz japonais[Noun]
+salability     vendabilite/[Adjective]
+salacious      grivois[Adjective]
+salad  salade[Noun]
+salads salades[Noun]
+salamander     salamandre[Noun]
+salami salami[Noun]
+salaried       salarie/[Adjective]
+salaries       salaires[Noun]
+sale   solde[Noun]
+saleable       vendable[Adjective]
+saleroom       la salle des ventes[Noun]
+sales  les ventes[Noun]
+salesclerk     un vendeur
+salesgirl      une vendeuse[Noun]
+saleslady      une vendeuse[Noun]
+salesman       un vendeur[Noun]
+salesmanship   l'art de vendre[Noun]
+salesmen       les vendeurs[Noun]
+salespeople    les vendeurs[Noun]
+salesperson    un vendeur[Noun]
+salesroom      les salles de ventes[Noun]
+saleswoman     une vendeuse
+saleswomen     les vendeuses[Noun]
+salient        saillant[Adjective]
+saline salin[Adjective]
+salinity       la salinité[Noun]
+salinometer    un salinomère[Noun]
+salinometers   des salinomètres[Noun]
+saliva salive[Noun]
+salivary       salivaire[Adjective]
+salivate       saliver[Verb]
+salivated       a fait saliver[Verb]
+salivates      fait saliver[Verb]
+salivating     faisant saliver[Verb]
+salivation     ;a salivation[Noun]
+sallies        les sorties[Noun]
+sallow jaunâtre[Adjective]
+sallowish      un peu jaunâtre[Adjective]
+salmon saumon[Noun]
+salmons        saumons[Noun]
+salon  salon[Noun]
+salons salons[Noun]
+salt   sel[Noun]
+saltwater      l'eau de mer[Noun]
+saltworks      la saline[Noun]
+saltwort       le soude ( bot.)[Noun]
+salty  sale/[Adjective]
+salubrious     salubre[Adjective]
+salubrity      la salubrité[Noun]
+salvage        le sauvetage[Noun]
+salver le plateau[Noun]
+samba  la Samba, une danse originée du Brasil[Noun]
+same   même[Adjective]
+sampan un bateua chinois[Noun]
+samphire       le passe-pierre  (bot.)[Noun]
+samurai        un guerrier ancien japonais[Noun]
+samurais       des guerriers anciens japonais[Noun]
+sand   le sable[Noun]
+sandal la sandale[Noun]
+school e/cole[Noun]
+sea    mer[Noun]
+sell   vendre[Verb]
+seller le vendeur[Noun]
+sellers        les vendeurs[Noun]
+serendipity    le serendiptiy[Verb]
+serene le serene
+seven  sept[Adverb]
+sevenfold      sept fois[Adverb]
+seventeen      dix-sept[Adverb]
+seventeenth    dix-septie\me[Adjective]
+seventh        septie\me[Adjective]
+seventies      les anne/es soixante-dix[Noun]
+seventieth     soixante-dixie\me[Adjective]
+seventy        soixante-dix[Adverb]
+seventyfold    soixante-dix fois[Adverb]
+sever  blesser[Verb]
+severalfold    plusieurs fois[Adverb]
+severe grave[Adjective]
+severed        blesse/ (m), blesse/e (f)[Adjective]
+severely       gravement[Adverb]
+severities     blessures (f)[Noun]
+severity       gravite/ (f)[Noun]
+sewage e/pandage (m)[Noun]
+sex    sexe (m)[Noun]
+sexagenarian   se/xage/naire[Adjective]
+shades lunettes de soleil (f)[Noun]
+shadow ombre (f)[Noun]
+shadows        ombres[Noun]
+shagreen       chagrin[Noun]
+shah   schah[Noun]
+shake  secouer[Verb]
+shakedown      lit de fortune[Noun]
+shaken secoue/[Adjective]
+shaky  tremblant[Adjective]
+shaman chaman[Noun]
+shamanism      chamanisme[Noun]
+shampoo        shampooing
+shampoos       shampooings
+sheep  agnis[Noun]
+sheepherder    pastor[Noun]
+ship   ba^teau
+ship   navire[Noun]
+shit   merde[Noun]
+sick   malade[Adverb]
+silver argent[Adjective]
+sing   chanter[Verb]
+singer chanteur[Noun]
+sink   couler[Verb]
+six    six[Adverb]
+sixteen        seize[Adverb]
+sixteenth      seizie\me[Adjective]
+sixties        les anne/es soixante (f)[Noun]
+sixty  soixante[Adverb]
+sixtyfold      soixante fois[Adverb]
+size   taille (f), dimension (f)[Noun]
+skate  patin (m)[Noun]
+skateboard     planche a\ roulettes (f)[Noun]
+skateboarder   planchiste (m)[Noun]
+skateboarding  faire de la planche a\ roulettes[Verb]
+skateboards    planches a\ roulettes (f)[Noun]
+skater patineur (m), patineuse (f)[Noun]
+skaters        patineurs (m), patineuses (f)[Noun]
+skates patins (m)[Noun]
+skating        patinage (m)[Noun]
+skill  Habilete/[Noun]
+skilled        habile[Adjective]
+skilless       maladroit[Adjective]
+skillful       adroit[Adjective]
+skills talents[Noun]
+sky    ciel[Noun]
+skylark        rossignol[Noun]
+skyscraper     gratte-ciel[Noun]
+snout  groin[Noun]
+snow   neige[Noun]
+snowball       boule de neige[Noun]
+snowflake      flocon de neige
+snowman        bonhomme de neige[Noun]
+snowstorm      tempe^te de neige[Noun]
+software       logiciel[Noun]
+sorrel oseille[Noun]
+sorrily        tristement[Adverb]
+sorrow tristesse[Noun]
+sort   trier[Verb]
+sorted trié[Adjective]
+sorter trieur[Noun]
+soul   Ã¢me[Noun]
+spectra        pl de spectrum, spectre[Noun]
+spectrum       Phys: spectre; Fig: gamme (de produit)[Noun]
+speculate      s'interroger, speculer, conjecturer[Verb]
+speculation    meditation; conjectures ; speculation
+staple agrafe[Noun]
+stapled        agraf/e[Adjective]
+stapler        agrafeuse[Noun]
+staplers       agrafeuses[Noun]
+staples        agrafes[Noun]
+star   e/toile[Noun]
+stars  e/toiles[Noun]
+start  de/part[Noun]
+stifled        e/touffe/
+strength       force[Noun]
+stupid Stupide[Adjective]
+subject        asignatura[Noun]
+succeed        re/ussir[Verb]
+success        re/ussite/[Noun]
+sun    soleil[Noun]
+sunbathe       se bronzer[Verb]
+sunny  ensoleille/[Adjective]
+suppressed     e/touffe/
+suspect        soupc,onner[Verb]
+swear  jurer ; preter serment[Verb]
+tab    happy[Adjective]
+tab    sortir[Verb]
+tabernacle     tabernacle[Noun]
+table  table[Noun]
+tableau        tableau[Noun]
+tableaus       tableaux[Noun]
+tableaux       tableaux[Noun]
+tablecloth     nappe[Noun]
+tablecloths    nappes[Noun]
+tables tables[Noun]
+tablet comprime/[Noun]
+tablets        comprime/s[Noun]
+taboo  tabou[Noun]
+taboos tabous[Noun]
+tachometer     tachyme\tre[Noun]
+tachometers    tachyme\tres[Noun]
+tacit  tacite[Adjective]
+tail   queue (of animal)[Noun]
+tailor tailleur[Noun]
+tailored       fait sur mesure[Adjective]
+tailors        tailleurs[Noun]
+tails  queues[Noun]
+task   tâche[Noun]
+tasks  tâches[Noun]
+taste  goût[Noun]
+tasted goûté[Verb]
+tasteless      insipide[Adjective]
+tear   accroc[Noun]
+tear   de/chirer[Verb]
+tear   de/chirure[Noun]
+tear   larme[Noun]
+teardrop       larme[Noun]
+tearful        tout en pleurs[Adjective]
+tearfully      en pleurant[Adverb]
+tearfully      les larmes aux yeux[Adverb]
+teargas        gaz lacrymoge\ne[Noun]
+tearjerker     me/lo[Noun]
+tearless       avec yeux secs[Adjective]
+tearless       sans larmes[Adjective]
+tearoom        salon de the/[Noun]
+tears  de/chirures[Noun]
+tears  larmes[Noun]
+tearstained    barbouille/ de larmes[Adjective]
+tearstained    portant des traces de larmes[Adjective]
+tease  taquin[Noun]
+tease  taquiner[Verb]
+tease  tourmenter[Verb]
+teasel carde\re[Noun]
+teaser question dificile[Noun]
+teaser taquin[Noun]
+teases excite[Verb]
+teases taquine[Verb]
+teases taquins[Noun]
+teasing        railleur[Adjective]
+teasing        taquinerie[Noun]
+teasingly      d'un ton railleur[Adverb]
+teasingly      pour taquiner[Verb]
+teaspoon       cuille\re a\ cafe/[Noun]
+teaspoon       cuiller a\ cafe/[Noun]
+teaspoonful    cuillere/e a\ cafe/[Noun]
+teat   bout de sein[Noun]
+teat   mamelon[Noun]
+teat   tette[Noun]
+teat   trayon[Noun]
+teatime        l'heure du the/[Noun]
+teats  mamelons[Noun]
+teats  tettes[Noun]
+ten    dix[Adverb]
+tendencies     tendances (f)[Noun]
+tendency       tendance (f)[Noun]
+tenderfoot     visage pa^le (m)[Noun]
+tenderly       tendrement[Adverb]
+thence de la\[Adverb]
+thence pour cette raison[Adverb]
+thenceforth    de\s lors[Adverb]
+thenceforward  de\s lors[Adverb]
+theocracy      the/ocratie[Noun]
+theocratic     the/ocratique[Adjective]
+theodolite     the/odolite[Noun]
+theologian     the/ologien[Noun]
+theologians    the/ologiens
+theological    the/ologique[Adjective]
+theologically  the/ologiquement[Adverb]
+theology       the/ologie[Noun]
+theorem        the/ore\me[Noun]
+theorems       the/ore\mes[Noun]
+theoretical    the/ore/tique[Adjective]
+theoretical    the/orique[Adjective]
+theoretically  the/oriquement[Adverb]
+theoretician   the/oricien[Noun]
+theoretician   the/oricienne[Noun]
+theoreticians  the/oriciennes[Noun]
+theoreticians  the/oriciens[Noun]
+theories       the/ories[Noun]
+theorist       the/oricien[Noun]
+theorist       the/oricienne[Noun]
+theorists      the/oriciennes[Noun]
+theorists      the/oriciens[Noun]
+theorize       the/oriser[Verb]
+thief  voleur[Noun]
+though cependant, pourtant[Adverb]
+though quoique , bien que[Conjunction]
+thought        pensee,idee[Noun]
+thought        reflexion; intention, dessein[Noun]
+thoughtful     pensif, meditatif, reveur[Adjective]
+thoughtful     serieux, reflechi, prudent[Adjective]
+thoughtfully   pensivement[Adverb]
+thoughtfulness meditation, recueillement[Adjective]
+thoughtless    irreflechi, etourdi[Adjective]
+thoughtlessly  etourdiment, a la legere, sans reflexion[Adverb]
+thoughtlessness        irreflexon, etourderie[Noun]
+thousand       mille, millier[Noun]
+thousandth     millieme[Noun]
+thrash ecraser qn, rouer qn de coup, [Verb]
+thrash se debattre, se demener[Verb]
+thread enfiler (une aiguille); se faufiler ; fileter[Verb]
+thread filament, fil de soie[Noun]
+thread Filet, pas de vis [Noun]
+threadbare     elime, rape, use[Adjective]
+threat menace[Noun]
+threaten       menacer[Verb]
+threatening    menacant[Adjective]
+threateningly  d'un ton menacant[Adverb]
+three  trois[Article]
+tigress        tiger[Noun]
+today  au'jour d'hui[Noun]
+toe    doigt a pied[Noun]
+tradition      tradition[Noun]
+traditional    traditional[Adjective]
+trail  piste[Noun]
+train  train[Noun]
+trainee        stagiare[Noun]
+trainer        encadreur[Noun]
+traitor        trai^tre[Noun]
+transaction    transaction[Noun]
+transalpine    transalpin[Adjective]
+transcribe     transcrire[Verb]
+transfer       transfert[Noun]
+translate      traduire[Verb]
+translation    traduction[Noun]
+translator     traducteur[Noun]
+transmit       transmettre[Verb]
+tree   arbre[Noun]
+truck  camion
+two    deux[Article]
+ubiquitous     omnipre/sent[Adjective]
+ubiquity       ubiquite/[Noun]
+udder  pis[Noun]
+ugh    pouah
+uglier plus laid[Adjective]
+ugliest        le plus laid[Adjective]
+uglify enlaidir[Verb]
+uglily laidement
+ugliness       laideur[Noun]
+ugly   laid[Adjective]
+ukulele        guitare hawai.enne[Noun]
+ulcer  ulce\re[Noun]
+ulcerate       ulce/rer[Verb]
+ulcerated      ulce/reux[Adjective]
+ulceration     ulce/ration[Noun]
+ulcerative     ulce/ratif[Adjective]
+ulna   cubitus[Noun]
+ultimo du mois dernier[Adverb]
+unemployment   chomage[Noun]
+vacant (room, seat) libre; (stare) vague; (post) vacant[Adjective]
+vacate quitter[Verb]
+vacation       vacances[Noun]
+vaccinate      vacciner[Verb]
+vaccinated     vacciner
+vacuum vide; (vacuum cleaner) aspirateur [masc] [Noun]
+vacuumed       passer a\ l'aspirateur[Verb]
+vagina vagin (masc.)[Noun]
+vagrant        vagabond(e) [m(f)][Noun]
+vague  vague; (outline, photograph) flou; (absent minded) distrait[Adjective]
+vain   (hope) vain; (promise) vide; (conceited) vaniteux, [f] -euse  [Adjective]
+wacky  drole[Adjective]
+wag    remuer[Verb]
+walnut la noix[Noun]
+warehouse      entrepot
+warehouse      entrepôt[Noun]
+warehouses     entrepôts[Noun]
+wash   laver[Verb]
+weep   pleurer[Verb]
+weeping        pleurs[Noun]
+weeping        qui pleure[Adjective]
+weeps  pleure[Verb]
+weepy  larmoyant[Adjective]
+weepy  me/lo[Noun]
+weevil charanc,on[Noun]
+weft   trame[Noun]
+weigh  mesurer[Verb]
+weigh  peser[Verb]
+weighing       pese/e[Noun]
+weighings      pese/es[Noun]
+weighs pe\se[Verb]
+weight poids[Noun]
+weighted       leste/[Adjective]
+weighted       ponde/re/[Adjective]
+weightily      avec force[Adverb]
+weightily      puissamment[Adverb]
+weighting      lestage[Noun]
+weighting      plombage[Noun]
+weightless     e/tat d'apesanteur[Adjective]
+weightlessness apesanteur[Noun]
+weights        attache un poids a\[Verb]
+weights        se/rie de poids[Noun]
+weighty        lourd[Adjective]
+weighty        pesant[Adjective]
+weir   barrage[Noun]
+weird  bizarre[Adjective]
+weird  e/trange[Adjective]
+weirdie        excentrique[Noun]
+weirdies       excentriques[Noun]
+weirdly        e/trangement[Adverb]
+weirdness      caracte\re e/trange[Noun]
+weirdness      e/trangete/ inquie/tante[Noun]
+weirdo excentrique[Noun]
+weirdos        excentriques[Noun]
+weirs  barrages[Noun]
+welcome        agre/able[Adjective]
+welcome        bienvenu[Adjective]
+welcome        bienvenue[Noun]
+welcome        souhaiter la bienvenue a\[Verb]
+where  ou\[Adjective]
+window la fene^tre[Noun]
+window le guichet  [tickets, etc.]
+windowpane     la glace[Noun]
+windowpanes    les glaces
+windows        les fene^tres
+windshield     le parebrise[Noun]
+windstorm      la tempe^te[Noun]
+windup remonter[Verb]
+wine   le vin[Noun]
+wineglass      le verre de vin[Noun]
+winegrower     le vigneron[Noun]
+winemaker      l'encaveur (m)[Noun]
+winemaking     la vinification[Noun]
+winepress      le pressoir[Noun]
+wines  les vins[Noun]
+winey  vineux (-se)[Adjective]
+wing   l'aile (f)[Noun]
+winglet        l'aileron (m)[Noun]
+wink   un clin d'oeil[Noun]
+winter l'hiver (m)
+wipe   essuyer
+wire   fil me/tallique, fil de fer[Noun]
+wire   telegramme[Noun]
+wire   telegraphier ; faire l'installation electrique[Verb]
+wired  branche , sonorise[Adjective]
+wireless       sans fil[Adjective]
+wiring installation electrique[Noun]
+wiry   raide, rude ; maigre et nerveux
+wisdom sagesse[Noun]
+wise   sage, prudent, savant[Adjective]
+wisecrack      astuce, sarcasme[Noun]
+wisely sagement, prudement[Adverb]
+wiser  plus sage[Adjective]
+wish   desir, souhait[Noun]
+wish   desirer, souhaiter qch[Verb]
+wishbone       brechet[Noun]
+wishes pl de wish, desir[Noun]
+wishful        that's wishfull thinking (on your part ): tu te fais des illusions[Adjective]
+witch  sorcie\re[Noun]
+witches        sorcie\res[Noun]
+with   avec[Conjunction]
+withdraw       retirer[Verb]
+withdraw       se retirer [intr]
+without        sans
+witness        te/moigner[Verb]
+witness        te/moin[Noun]
+witnesses      te/moins[Noun]
+wolverine      le carcajou[Noun]
+wolverine      le glouton[Noun]
+world  le monde[Noun]
+worldwide      mondial[Adjective]
+xenophobe      xe/nophobe[Noun]
+xenophobia     xénophobie[Noun]
+xenophobic     xe/nophobe[Adjective]
+xerographic    xe/rographique[Adjective]
+xylem  xyle\me[Noun]
+xylene xyle\ne[Noun]
+xylophone      xylophone[Noun]
+xylophones     xylophone[Noun]
+xylophonist    joueur (joueuse) de xylophone[Noun]
+xylose xylose[Noun]
+xylotomic      xylotomique[Adjective]
+yacht  yacht[Noun]
+yachting       yachting[Noun]
+yachtsman      yachtsman
+yak    yack[Noun]
+yam    patate douce[Noun]
+yank   tirer d'un coup sec[Verb]
+yap    japper[Verb]
+yard   yard (3 ft)[Noun]
+yardstick      mesure[Noun]
+yarn   fil[Noun]
+yawn   bâillement[Noun]
+yawn   bâiller[Verb]
+yawning        ba^illement[Noun]
+yeah   ouais!
+year   année[Noun]
+yearbook       annuaire[Noun]
+yearlong       annuel[Noun]
+yearly annuel(le)[Adjective]
+yearly annuellement[Adverb]
+yearn  désirer[Verb]
+yearning       de/sir[Noun]
+yearningly     de/sireux[Adjective]
+years  années[Noun]
+yeast  levure[Noun]
+yell   hurlement[Noun]
+yell   hurler[Verb]
+yellow jaune[Adjective]
+yellowed       jauni[Adjective]
+yellowing      jaunissant[Adjective]
+yellowish      jauna^tre[Adjective]
+yes    oui
+yesterday      hier[Noun]
+yet    encore[Adverb]
+yew    if[Noun]
+yield  produire[Verb]
+yoga   yoga[Noun]
+yoghurt        yaourt[Noun]
+yogurt yaourt[Noun]
+yoke   joug[Noun]
+yolk   jaune d'oeuf[Noun]
+you    (formal and/or plural) vous[Pronoun]
+you    (informal and singular) tu[Pronoun]
+young  jeune[Adjective]
+younger        plus jeune[Adjective]
+youngster      jeune[Noun]
+youth  jeunesse[Adjective]
+youthful       juvénile[Adjective]
+yuppie yuppie[Noun]
+zabaglione     sabayon[Noun]
+zany   dingue[Adjective]
+zazen  zazen[Noun]
+zeal   zèle[Noun]
+zealous        zélé(e)[Adjective]
+zebra  zèbre[Noun]
+zenith zénith[Noun]
+zero   zero[Noun]
+zero   zéro
+zest   piquant[Noun]
+zigzag zigzaguer[Verb]
+zinc   zinc[Noun]
+zipper fermeture[Noun]
+zodiac zodiaque[Noun]
+zodiac zondiaque[Noun]
+zone   zone[Noun]
+zone   zone[Noun]
+zoo    zoo[Noun]
+zoology        zoologie[Noun]
+zoom   aller en trombe[Verb]
+zucchini       courgette[Noun]
diff --git a/pkgs/thread2.8.0/tests/store-load.tcl b/pkgs/thread2.8.0/tests/store-load.tcl
new file mode 100644 (file)
index 0000000..4907349
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/bin/env tclsh
+
+lappend auto_path .
+package require Thread
+
+if {[llength $argv] != 3} {
+    puts "Usage: $argv0 handle path times"
+    puts {
+    handle
+        A persistent storage handle (see [tsv::array bind] manpage).
+    path
+        The path to file containing lines in the form of "key<tab>val", where
+        key is a single-word and val is everyting else.
+    times
+        The number of times to reload the data from persistent storage.
+
+    This script reads lines of data from <path> and stores them into the
+    persistent storage described by <handle>. Values for duplicate keys are
+    handled as a lists. The persistent storage engine is then stress-tested by
+    reloading the whole store <times> times.
+    }
+    exit 1
+}
+
+lassign $argv handle path times
+
+### Cleanup
+set filename [string range $handle [string first : $handle]+1 end]
+file delete -force $filename
+
+### Load and store tab-separated values
+tsv::array bind a $handle
+set fd [open $path r]
+set start [clock milliseconds]
+set pairs 0
+while {[gets $fd line] >  0} {
+    if {[string index $line 0] eq {#}} {
+        continue
+    }
+    set tab [string first {    } $line]
+    if {$tab == -1} {
+        continue
+    }
+
+    set k [string range $line 0 $tab-1]
+    set v [string range $line $tab+1 end]
+
+    if {![tsv::exists a $k]} {
+        incr pairs
+    }
+
+    tsv::lappend a $k $v
+}
+puts "Stored $pairs pairs in [expr {[clock milliseconds]-$start}] milliseconds"
+
+tsv::array unbind a
+tsv::unset a
+
+### Reload
+set pairs 0
+set iter [time {
+    tsv::array bind a $handle
+    set pairs [tsv::array size a]
+    tsv::array unbind a
+    tsv::unset a
+} $times]
+puts "Loaded $pairs pairs $times times at $iter"
+
+## Dump file stats
+puts "File $filename is [file size $filename] bytes long"
similarity index 98%
rename from pkgs/thread2.7.3/tests/thread.test
rename to pkgs/thread2.8.0/tests/thread.test
index c41867c..a710d30 100644 (file)
@@ -147,6 +147,26 @@ test thread-7.0 {thread::exit} {
     set c
 } {666}
 
+test thread-7.1 {thread::exit - # args} {
+    set tid [thread::create]
+    catch {thread::send $tid {thread::exit 1 0}} msg
+    set msg
+} {wrong # args: should be "thread::exit ?status?"}
+
+test thread-7.2 {thread::exit - args} {
+    set tid [thread::create]
+    catch {thread::send $tid {thread::exit foo}} msg
+    set msg
+} {expected integer but got "foo"}
+
+test thread-7.3 {thread::exit - status} {
+    ThreadReap
+    set tid [thread::create -joinable {thread::exit 0}]
+    set c [thread::join $tid]
+    ThreadReap
+    set c
+} {0}
+
 test thread-8.0 {thread::exists - true} {
     ThreadReap
     set c [thread::exists [thread::create]]
@@ -472,7 +492,7 @@ test thread-17.2 {thread::transfer - target thread dying} {chanTransfer} {
 
 test thread-17.3 {thread::transfer - clearing of fileevents} {chanTransfer} {
     proc _HandleIt_ {} {
-        global gotEvents tid file    
+        global gotEvents tid file
         if {$gotEvents == 0} {
             thread::transfer $tid $file
             # From now on no events should be delivered anymore,
@@ -994,8 +1014,8 @@ test thread-20.14 {thread::mutex - write-lock write-locked mutex} {
 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 
+    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}}
diff --git a/pkgs/thread2.8.0/tests/tkt-84be1b5a73.test b/pkgs/thread2.8.0/tests/tkt-84be1b5a73.test
new file mode 100644 (file)
index 0000000..946c6db
--- /dev/null
@@ -0,0 +1,25 @@
+package require tcltest
+namespace import ::tcltest::*
+tcltest::loadTestedCommands
+package require Thread
+
+# This test used to segfault before commit f4c95731c0.
+test tkt-84be1b5a73 {Ticket 84be1b5a73} -body {
+    set t [thread::create]
+    set resultvar() {}
+
+    trace add variable resultvar() write {
+        unset -nocomplain resultvar()
+        list}
+
+    proc errorproc {tid einfo} {}
+    thread::errorproc errorproc
+    thread::send -async $t {
+        error ""
+    } resultvar()
+
+    after 1000 {
+        set forever 1
+    }
+    vwait forever
+} -returnCodes 0
diff --git a/pkgs/thread2.8.0/tests/tsv.test b/pkgs/thread2.8.0/tests/tsv.test
new file mode 100644 (file)
index 0000000..d25b052
--- /dev/null
@@ -0,0 +1,107 @@
+package require tcltest
+namespace import ::tcltest::*
+tcltest::loadTestedCommands
+package require Thread
+
+set backends {gdbm lmdb}
+
+foreach b $backends {
+    testConstraint have_$b [expr {$b in [tsv::handlers]}]
+}
+
+foreach backend $backends {
+    set db "data"
+    file delete -force $db
+    set ::handle $backend:$db
+
+    proc setup {} {
+        tsv::array bind a $::handle
+    }
+    proc cleanup {} {
+        tsv::array unbind a
+    }
+
+    test tsv-$backend-1.0 {tsv::array isboud} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::array isbound a
+    } -cleanup {
+        cleanup
+    } -result {1}
+
+    test tsv-$backend-1.1 {tsv::array bind - empty} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::array names b
+    } -cleanup {
+       cleanup
+    } -result {}
+
+    test tsv-$backend-1.2 {tsv::set} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::set a Key Val
+    } -cleanup {
+        cleanup
+    } -result {Val}
+
+    test tsv-$backend-1.3 {tsv::get - previously set was persisted} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::get a Key
+    } -cleanup {
+        cleanup
+    } -result {Val}
+
+    test tsv-$backend-1.4 {tsv::array names - previously set was persisted} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::array names a
+    } -cleanup {
+        cleanup
+    } -result {Key}
+
+    test tsv-$backend-1.5 {tsv::exists - previously set exists} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::exists a Key
+    } -cleanup {
+        cleanup
+    } -result {1}
+
+    test tsv-$backend-1.6 {tsv::pop - get previously set} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::pop a Key
+    } -cleanup {
+        cleanup
+    } -result {Val}
+
+    test tsv-$backend-1.7 {tsv::exists - popped was removed} \
+    -constraints have_$backend \
+    -setup {
+        setup
+    } -body {
+        tsv::exists a Key
+    } -cleanup {
+        cleanup
+    } -result {0}
+
+    file delete -force $db
+}
+
+::tcltest::cleanupTests
similarity index 96%
rename from pkgs/thread2.7.3/unix/CONFIG
rename to pkgs/thread2.8.0/unix/CONFIG
index ecc7efe..cd3f23f 100644 (file)
 # 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". 
+# 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
 #
 #
similarity index 98%
rename from pkgs/thread2.7.3/unix/README
rename to pkgs/thread2.8.0/unix/README
index 4ca4c5c..3b5e1db 100644 (file)
@@ -11,7 +11,7 @@ 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 
+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:
 
@@ -22,7 +22,7 @@ Either way, this will create a Makefile which you use to run "make" and
 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 run the regression tests on the package.
 
 To explore other building options, look into the CONFIG file for more
 information.
@@ -56,10 +56,10 @@ 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 
+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 
+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
similarity index 99%
rename from pkgs/thread2.7.3/win/CONFIG
rename to pkgs/thread2.8.0/win/CONFIG
index df5aac1..471d89e 100644 (file)
@@ -14,7 +14,7 @@
 # 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
similarity index 94%
rename from pkgs/thread2.7.3/win/README.txt
rename to pkgs/thread2.8.0/win/README.txt
index 596623b..b46689b 100644 (file)
@@ -47,16 +47,16 @@ the F7 key to build the extension under the control of the MSVC IDE.
 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 
+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 
+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. 
+and fetch yourself a compiled GNU Gdbm DLL.
 
 -EOF-
similarity index 66%
rename from pkgs/thread2.7.3/win/pkg.vc
rename to pkgs/thread2.8.0/win/pkg.vc
index 817b302..6c8ea5e 100644 (file)
@@ -2,5 +2,5 @@
 # (then re-autoconf)\r
 \r
 PACKAGE_MAJOR  = 2\r
-PACKAGE_MINOR  = 7\r
-PACKAGE_VERSION        = "2.7.3"\r
+PACKAGE_MINOR  = 8\r
+PACKAGE_VERSION        = "2.8.0"\r
similarity index 94%
rename from pkgs/thread2.7.3/win/thread_win.dsp
rename to pkgs/thread2.8.0/win/thread_win.dsp
index f46c06c..0c1e0bc 100644 (file)
@@ -7,19 +7,19 @@
 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\r
 !MESSAGE NMAKE /f "thread_win.mak".\r
-!MESSAGE \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\r
 !MESSAGE NMAKE /f "thread_win.mak" CFG="thread - Win32 Debug"\r
-!MESSAGE \r
+!MESSAGE\r
 !MESSAGE Possible choices for configuration are:\r
-!MESSAGE \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
+!MESSAGE\r
 \r
 # Begin Project\r
 # PROP AllowPerConfigDependencies 0\r
@@ -68,7 +68,7 @@ CFG=thread - Win32 Debug
 # PROP Bsc_Name ""\r
 # PROP Target_Dir ""\r
 \r
-!ENDIF \r
+!ENDIF\r
 \r
 # Begin Target\r
 \r
@@ -79,7 +79,7 @@ CFG=thread - Win32 Debug
 \r
 !ELSEIF  "$(CFG)" == "thread - Win32 Debug"\r
 \r
-!ENDIF \r
+!ENDIF\r
 \r
 ROOT=..\r
 \r
index b0487e6..a9c77e3 100644 (file)
@@ -3279,6 +3279,92 @@ test assemble-51.4 {memory leak testing} memory {
        }
     }
 } 0
+
+test assemble-52.1 {Bug 3154ea2759} {
+    apply {{} {
+       # Needs six exception ranges to force the range allocations to use the
+       # malloced store.
+       ::tcl::unsupported::assemble {
+           beginCatch @badLabel
+           push error
+           push testing
+           invokeStk 2
+           pop
+           push 0
+           jump @okLabel
+           label @badLabel
+           push 1;             # should be pushReturnCode
+           label @okLabel
+           endCatch
+           pop
+           
+           beginCatch @badLabel2
+           push error
+           push testing
+           invokeStk 2
+           pop
+           push 0
+           jump @okLabel2
+           label @badLabel2
+           push 1;             # should be pushReturnCode
+           label @okLabel2
+           endCatch
+           pop
+           
+           beginCatch @badLabel3
+           push error
+           push testing
+           invokeStk 2
+           pop
+           push 0
+           jump @okLabel3
+           label @badLabel3
+           push 1;             # should be pushReturnCode
+           label @okLabel3
+           endCatch
+           pop
+           
+           beginCatch @badLabel4
+           push error
+           push testing
+           invokeStk 2
+           pop
+           push 0
+           jump @okLabel4
+           label @badLabel4
+           push 1;             # should be pushReturnCode
+           label @okLabel4
+           endCatch
+           pop
+           
+           beginCatch @badLabel5
+           push error
+           push testing
+           invokeStk 2
+           pop
+           push 0
+           jump @okLabel5
+           label @badLabel5
+           push 1;             # should be pushReturnCode
+           label @okLabel5
+           endCatch
+           pop
+           
+           beginCatch @badLabel6
+           push error
+           push testing
+           invokeStk 2
+           pop
+           push 0
+           jump @okLabel6
+           label @badLabel6
+           push 1;             # should be pushReturnCode
+           label @okLabel6
+           endCatch
+           pop
+       }
+    }}
+} {};                          # must not crash
 \f
 rename fillTables {}
 rename assemble {}
index 2738fc6..9a27233 100644 (file)
@@ -4160,12 +4160,20 @@ test chan-io-33.4 {Tcl_Gets with long line} -setup {
 } -cleanup {
     chan close $f
 } -result {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
-test chan-io-33.5 {Tcl_Gets with long line} {
+test chan-io-33.5 {Tcl_Gets with long line} -setup {
+    set f [open $path(test3) w]
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    close $f
+} -body {
     set f [open $path(test3)]
     set x [chan gets $f y]
     chan close $f
     list $x $y
-} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+} -result {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
 test chan-io-33.6 {Tcl_Gets and end of file} -setup {
     file delete $path(test3)
     set x {}
@@ -6765,7 +6773,12 @@ test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} {
     chan close $out
     file size $path(utf8-fcopy.txt)
 } 5
-test chan-io-52.11 {TclCopyChannel & encodings} {fcopy} {
+test chan-io-52.11 {TclCopyChannel & encodings} -setup {
+    set f [open $path(utf8-fcopy.txt) w]
+    fconfigure $f -encoding utf-8
+    puts $f "\u0410\u0410"
+    close $f
+} -constraints {fcopy} -body {
     # binary to encoding => the input has to be in utf-8 to make sense to the
     # encoder
     set in  [open $path(utf8-fcopy.txt) r]
@@ -6777,7 +6790,7 @@ test chan-io-52.11 {TclCopyChannel & encodings} {fcopy} {
     chan close $in
     chan close $out
     file size $path(kyrillic.txt)
-} 3
+} -result 3
 
 test chan-io-53.1 {CopyData} -setup {
     file delete $path(test1)
index 64cfeba..b4ef605 100644 (file)
@@ -141,9 +141,13 @@ test cmdAH-2.6.2 {cd} -constraints {unix nonPortable} -setup {
 } -cleanup {
     cd $dir
 } -result {/}
-test cmdAH-2.6.3 {Tcl_CdObjCmd, bug #3118489} -returnCodes error -body {
+test cmdAH-2.6.3 {Tcl_CdObjCmd, bug #3118489} -setup {
+    set dir [pwd]
+} -returnCodes error -body {
     cd .\0
-} -result "couldn't change working directory to \".\0\": no such file or directory"
+} -cleanup {
+    cd $dir
+} -match glob -result "couldn't change working directory to \".\0\": *"
 test cmdAH-2.7 {Tcl_ConcatObjCmd} {
     concat
 } {}
@@ -878,20 +882,20 @@ test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unix testchmod} {
 } 1
 test cmdAH-18.5 {Tcl_FileObjCmd: executable} -constraints {win} -body {
     # On pc, must be a .exe, .com, etc.
-    set x [file exe $gorpfile]
-    set gorpexe [makeFile foo gorp.exe]
-    lappend x [file exe $gorpexe]
-} -cleanup {
-    removeFile $gorpexe
-} -result {0 1}
-test cmdAH-18.5.1 {Tcl_FileObjCmd: executable} -constraints {win} -body {
-    # On pc, must be a .exe, .com, etc.
-    set x [file exe $gorpfile]
-    set gorpexe [makeFile foo gorp.exe]
-    lappend x [file exe [string toupper $gorpexe]]
+    set x {}
+    set gorpexes {}
+    foreach ext {exe com cmd bat} {
+        lappend x [file exe nosuchfile.$ext]
+        set gorpexe [makeFile foo gorp.$ext]
+        lappend gorpexes $gorpexe
+        lappend x [file exe $gorpexe] [file exe [string toupper $gorpexe]]
+    }
+    set x
 } -cleanup {
-    removeFile $gorpexe
-} -result {0 1}
+    foreach gorpexe $gorpexes {
+        removeFile $gorpexe
+    }
+} -result {0 1 1 0 1 1 0 1 1 0 1 1}
 test cmdAH-18.6 {Tcl_FileObjCmd: executable} {} {
     # Directories are always executable.
     file exe $dirfile
@@ -1027,6 +1031,16 @@ test cmdAH-20.6 {Tcl_FileObjCmd: atime touch} -setup {
     set modatime [file atime $file $newatime]
     expr {$newatime == $modatime ? 1 : "$newatime != $modatime"}
 } -result 1
+test cmdAH-20.7 {
+    Tcl_FileObjCmd: atime (built-in Windows names)
+} -constraints {win} -body {
+    file atime con
+} -result "could not get access time for file \"con\"" -returnCodes error
+test cmdAH-20.7.1 {
+    Tcl_FileObjCmd: atime (built-in Windows names with dir path and extension)
+} -constraints {win} -body {
+    file atime [file join [temporaryDirectory] CON.txt]
+} -result "could not get access time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error
 
 if {[testConstraint unix] && [file exists /tmp]} {
     removeFile touch.me /tmp
@@ -1258,6 +1272,16 @@ test cmdAH-24.13 {Tcl_FileObjCmd: directory mtime} -setup {
 } -cleanup {
     file delete -force $dirname
 } -result {0 1}
+test cmdAH-24.14 {
+    Tcl_FileObjCmd: mtime (built-in Windows names)
+} -constraints {win} -body {
+    file mtime con
+} -result "could not get modification time for file \"con\"" -returnCodes error
+test cmdAH-24.14.1 {
+    Tcl_FileObjCmd: mtime (built-in Windows names with dir path and extension)
+} -constraints {win} -body {
+    file mtime [file join [temporaryDirectory] CON.txt]
+} -result "could not get modification time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error
 
 # owned
 test cmdAH-25.1 {Tcl_FileObjCmd: owned} -returnCodes error -body {
@@ -1277,6 +1301,12 @@ test cmdAH-25.2.1 {Tcl_FileObjCmd: owned} -constraints unix -setup {
 test cmdAH-25.3 {Tcl_FileObjCmd: owned} {unix notRoot} {
     file owned /
 } 0
+test cmdAH-25.3.1 {Tcl_FileObjCmd: owned} -constraints win -body {
+    file owned $env(windir)
+} -result 0
+test cmdAH-25.4 {Tcl_FileObjCmd: owned} -body {
+    file owned nosuchfile
+} -result 0
 
 # readlink
 test cmdAH-26.1 {Tcl_FileObjCmd: readlink} -returnCodes error -body {
@@ -1307,6 +1337,16 @@ test cmdAH-27.2 {Tcl_FileObjCmd: size} {
 test cmdAH-27.3 {Tcl_FileObjCmd: size} {
     list [catch {file size _bogus_} msg] [string tolower $msg] $errorCode
 } {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-27.4 {
+    Tcl_FileObjCmd: size (built-in Windows names)
+} -constraints {win} -body {
+    file size con
+} -result 0
+test cmdAH-27.4.1 {
+    Tcl_FileObjCmd: size (built-in Windows names with dir path and extension)
+} -constraints {win} -body {
+    file size [file join [temporaryDirectory] con.txt]
+} -result 0
 
 catch {testsetplatform $platform}
 removeFile $gorpfile
@@ -1398,12 +1438,24 @@ test cmdAH-28.12 {Tcl_FileObjCmd: stat} -setup {
 } -cleanup {
     removeFile $filename
 } -result 1
+test cmdAH-28.13 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {win} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat con stat
+    lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}
+} -result {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
+test cmdAH-28.13.1 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {win} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat [file join [temporaryDirectory] CON.txt] stat
+    lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}
+} -result {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
 unset -nocomplain stat
 
 # type
 test cmdAH-29.1 {Tcl_FileObjCmd: type} -returnCodes error -body {
-    file size a b
-} -result {wrong # args: should be "file size name"}
+    file type a b
+} -result {wrong # args: should be "file type name"}
 test cmdAH-29.2 {Tcl_FileObjCmd: type} {
     file type $dirfile
 } directory
@@ -1438,6 +1490,16 @@ test cmdAH-29.4.1 {Tcl_FileObjCmd: type} -constraints {linkDirectory} -setup {
 test cmdAH-29.5 {Tcl_FileObjCmd: type} {
     list [catch {file type _bogus_} msg] [string tolower $msg] $errorCode
 } {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-29.6 {
+    Tcl_FileObjCmd: type (built-in Windows names)
+} -constraints {win} -body {
+    file type con
+} -result "characterSpecial"
+test cmdAH-29.6.1 {
+    Tcl_FileObjCmd: type (built-in Windows names, with dir path and extension)
+} -constraints {win} -body {
+    file type [file join [temporaryDirectory] CON.txt]
+} -result "characterSpecial"
 
 # Error conditions
 test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
index 46e678a..f021cf2 100644 (file)
@@ -224,6 +224,17 @@ test compile-5.2 {TclCompileForeachCmd: non-local variables} {
     foreach-test
     set ::foo
 } 3
+test compile-5.3 {TclCompileForeachCmd: [Bug b9b2079e6d]} -setup {
+    proc demo {} {
+       foreach x y {
+           if 1 break else
+       }
+    }
+} -body {
+    demo
+} -cleanup {
+    rename demo {}
+} -returnCodes error -result {wrong # args: no script following "else" argument}
 
 test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} -setup {
     catch {unset x}
@@ -667,7 +678,7 @@ test compile-17.2 {Command interpretation binding for non-compiled code} -setup
 # change without warning.
 
 set disassemblables [linsert [join {
-    lambda method objmethod proc script
+    constructor destructor lambda method objmethod proc script
 } ", "] end-1 or]
 test compile-18.1 {disassembler - basics} -returnCodes error -body {
     tcl::unsupported::disassemble
@@ -861,6 +872,103 @@ test compile-18.39 {disassembler - basics} -setup {
 } -cleanup {
     foo destroy
 } -result "$bytecodekeys initiallinenumber sourcefile"
+test compile-18.40 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble constructor
+} -match glob -result {wrong # args: should be "* constructor className"}
+test compile-18.41 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble constructor nosuchclass
+} -result {nosuchclass does not refer to an object}
+test compile-18.42 {disassembler - basics} -returnCodes error -setup {
+    oo::object create justanobject
+} -body {
+    tcl::unsupported::disassemble constructor justanobject
+} -cleanup {
+    justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.43 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::disassemble constructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined constructor}
+test compile-18.44 {disassembler - basics} -setup {
+    oo::class create foo {constructor {} {set x 1}}
+} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble constructor foo
+} -cleanup {
+    foo destroy
+} -match glob -result *
+test compile-18.45 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode constructor
+} -match glob -result {wrong # args: should be "* constructor className"}
+test compile-18.46 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode constructor nosuchobject
+} -result {nosuchobject does not refer to an object}
+test compile-18.47 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::getbytecode constructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined constructor}
+test compile-18.48 {disassembler - basics} -setup {
+    oo::class create foo {constructor {} {set x 1}}
+} -body {
+    dict keys [tcl::unsupported::getbytecode constructor foo]
+} -cleanup {
+    foo destroy
+} -result "$bytecodekeys"
+# There is no compile-18.49
+test compile-18.50 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble destructor
+} -match glob -result {wrong # args: should be "* destructor className"}
+test compile-18.51 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble destructor nosuchclass
+} -result {nosuchclass does not refer to an object}
+test compile-18.52 {disassembler - basics} -returnCodes error -setup {
+    oo::object create justanobject
+} -body {
+    tcl::unsupported::disassemble destructor justanobject
+} -cleanup {
+    justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.53 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::disassemble destructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined destructor}
+test compile-18.54 {disassembler - basics} -setup {
+    oo::class create foo {destructor {set x 1}}
+} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble destructor foo
+} -cleanup {
+    foo destroy
+} -match glob -result *
+test compile-18.55 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode destructor
+} -match glob -result {wrong # args: should be "* destructor className"}
+test compile-18.56 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode destructor nosuchobject
+} -result {nosuchobject does not refer to an object}
+test compile-18.57 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::getbytecode destructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined destructor}
+test compile-18.58 {disassembler - basics} -setup {
+    oo::class create foo {destructor {set x 1}}
+} -body {
+    dict keys [tcl::unsupported::getbytecode destructor foo]
+} -cleanup {
+    foo destroy
+} -result "$bytecodekeys"
 
 test compile-19.0 {Bug 3614102: reset stack housekeeping} -body {
     # This will panic in a --enable-symbols=compile build, unless bug is fixed.
index d5406d0..a6b0cb4 100644 (file)
@@ -2048,6 +2048,13 @@ test dict-24.25 {dict map with huge dict (compiled)} {
     }} 100000
 } 166666666600000
 
+test dict-25.1 {compiled dict update with low-refcount values [Bug d553228d9f]} {
+    # Test crashes on failure
+    apply {{} {
+       lassign {} item
+       dict update item item item two two {}
+    }}
+} {}
 \f
 # cleanup
 ::tcltest::cleanupTests
index 9f59fbc..0dd4f98 100644 (file)
@@ -19,7 +19,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
 # Some tests require the "exec" command.
 # Skip them if exec is not defined.
 testConstraint exec [llength [info commands exec]]
-
+\f
 #
 # These tests will run on any platform (and indeed crashed on the Mac). So put
 # them before you test for the existance of exec.
@@ -147,6 +147,7 @@ test env-2.2 {adding environment variables} -setup {
 } -result {NAME1=test string}
 test env-2.3 {adding environment variables} -setup {
     encoding system iso8859-1
+    set env(NAME1) "test string"
 } -constraints {exec} -body {
     set env(NAME2) "more"
     getenv
@@ -156,6 +157,8 @@ test env-2.3 {adding environment variables} -setup {
 NAME2=more}
 test env-2.4 {adding environment variables} -setup {
     encoding system iso8859-1
+    set env(NAME1) "test string"
+    set env(NAME2) "more"
 } -constraints {exec} -body {
     set env(XYZZY) "garbage"
     getenv
@@ -165,7 +168,9 @@ test env-2.4 {adding environment variables} -setup {
 NAME2=more
 XYZZY=garbage}
 
+set env(NAME1) "test string"
 set env(NAME2) "new value"
+set env(XYZZY) "garbage"
 test env-3.1 {changing environment variables} -setup {
     encoding system iso8859-1
 } -constraints {exec} -body {
@@ -177,6 +182,7 @@ test env-3.1 {changing environment variables} -setup {
 } -result {NAME1=test string
 NAME2=new value
 XYZZY=garbage}
+unset -nocomplain env(NAME2)
 
 test env-4.1 {unsetting environment variables: default} -setup {
     encoding system iso8859-1
@@ -195,6 +201,7 @@ test env-4.2 {unsetting environment variables} -setup {
     unset env(XYZZY)
     encoding system $sysenc
 } -result {XYZZY=garbage}
+unset -nocomplain env(NAME1) env(XYZZY)
 test env-4.3 {setting international environment variables} -setup {
     encoding system iso8859-1
 } -constraints {exec} -body {
@@ -213,6 +220,7 @@ test env-4.4 {changing international environment variables} -setup {
 } -result {\u00a7=\u00a7}
 test env-4.5 {unsetting international environment variables} -setup {
     encoding system iso8859-1
+    set env(\ua7) \ua7
 } -body {
     set env(\ub6) \ua7
     unset env(\ua7)
@@ -323,7 +331,7 @@ test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy
       return [info exists ::env(test7_3)]
     }}
 } -result 1
-
+\f
 # Restore the environment variables at the end of the test.
 
 foreach name [array names env] {
index 0d1b06c..207c799 100644 (file)
@@ -583,6 +583,34 @@ test event-11.6 {Tcl_VwaitCmd procedure: round robin scheduling, same source} {
     removeFile $test2file
     list $x $y $z
 } {3 3 done}
+test event-11.7 {Bug 16828b3744} {
+    after idle {
+       set ::t::v 1
+       namespace delete ::t
+    }
+    namespace eval ::t {
+       vwait ::t::v
+    }
+} {}
+test event-11.8 {Bug 16828b3744} -setup {
+    oo::class create A {
+       variable continue
+    
+       method start {} {
+           after idle [self] destroy
+        
+           set continue 0
+           vwait [namespace current]::continue
+       }
+       destructor {
+           set continue 1
+       }       
+    }
+} -body {
+    [A new] start
+} -cleanup {
+    A destroy
+} -result {}
 
 test event-12.1 {Tcl_UpdateCmd procedure} -returnCodes error -body {
     update a b
index 16a8320..38927d3 100644 (file)
@@ -682,6 +682,22 @@ test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
 } -cleanup {
     removeFile $tmpfile
 } -result 14
+
+# Tests to ensure batch files and .CMD (Bug 9ece99d58b)
+# can be executed on Windows
+test exec-20.0 {exec .bat file} -constraints {win} -body {
+    set log [makeFile {} exec20.log]
+    exec [makeFile "echo %1> $log" exec20.bat] "Testing exec-20.0"
+    viewFile $log
+} -result "\"Testing exec-20.0\""
+test exec-20.1 {exec .CMD file} -constraints {win} -body {
+    set log [makeFile {} exec201.log]
+    exec [makeFile "echo %1> $log" exec201.CMD] "Testing exec-20.1"
+    viewFile $log
+} -result "\"Testing exec-20.1\""
+    
+
+
 \f
 # ----------------------------------------------------------------------
 # cleanup
index 51f00d1..387d844 100644 (file)
@@ -1468,14 +1468,16 @@ if {[testConstraint testsetplatform]} {
 }
 test filename-17.2 {windows specific glob with executable} -body {
     makeDirectory execglob
-    makeFile contents execglob/abc.exe
-    makeFile contents execglob/abc.notexecutable
-    glob -nocomplain -dir [temporaryDirectory]/execglob -tails -types x *
+    foreach ext {exe com cmd bat notexecutable} {
+        makeFile contents execglob/abc.$ext
+    }
+    lsort [glob -nocomplain -dir [temporaryDirectory]/execglob -tails -types x *]
 } -constraints {win} -cleanup {
-    removeFile execglob/abc.exe
-    removeFile execglob/abc.notexecutable
+    foreach ext {exe com cmd bat ps1 notexecutable} {
+        removeFile execglob/abc.$ext
+    }
     removeDirectory execglob
-} -result {abc.exe}
+} -result {abc.bat abc.cmd abc.com abc.exe}
 test filename-17.3 {Bug 2571597} win {
     set p /a
     file pathtype $p
index c562796..7549beb 100644 (file)
@@ -233,6 +233,7 @@ if {[testConstraint history]} {
 test history-8.1 {clear option} history {catch {history clear junk}} 1
 test history-8.2 {clear option} history {history clear} {}
 if {[testConstraint history]} {
+    history clear
     history add "Testing"
 }
 test history-8.3 {clear option} history {history} {     1  Testing}
@@ -248,3 +249,7 @@ test history-9.2 {miscellaneous} history {
 # cleanup
 ::tcltest::cleanupTests
 return
+
+# Local Variables:
+# mode: tcl
+# End:
index 3057dd2..42f5a96 100644 (file)
@@ -1841,7 +1841,7 @@ test info-30.48 {Bug 2850901} testevalex {
 # -------------------------------------------------------------------------
 # literal sharing 2, bug 2933089
 
-test info-39.1 {location information not confused by literal sharing, bug 2933089} -setup {
+test info-40.1 {location information not confused by literal sharing, bug 2933089} -setup {
     set result {}
 
     proc print_one {} {}
@@ -2398,6 +2398,23 @@ test info-33.35 {{*}, literal, simple, bytecompiled} -body {
 # -------------------------------------------------------------------------
 unset -nocomplain res
 
+test info-39.1 {Bug 4b61afd660} -setup {
+    proc probe {} {
+       return [dict get [info frame -1] line]
+    }
+    set body {
+       set cmd probe
+       $cmd
+    }
+    proc demo {} $body
+} -body {
+    demo
+} -cleanup {
+    unset -nocomplain body
+    rename demo {}
+    rename probe {}
+} -result 3
+
 # cleanup
 catch {namespace delete test_ns_info1 test_ns_info2}
 ::tcltest::cleanupTests
index 4bc9fe2..f9c1aec 100644 (file)
@@ -71,9 +71,11 @@ test interp-2.2 {basic interpreter creation} {
 test interp-2.3 {basic interpreter creation} {
     catch {interp create -safe}
 } 0 
-test interp-2.4 {basic interpreter creation} {
-    list [catch {interp create a} msg] $msg
-} {1 {interpreter named "a" already exists, cannot create}}
+test interp-2.4 {basic interpreter creation} -setup {
+    catch {interp create a}
+} -returnCodes error -body {
+    interp create a
+} -result {interpreter named "a" already exists, cannot create}
 test interp-2.5 {basic interpreter creation} {
     interp create b -safe
 } b
@@ -89,11 +91,13 @@ test interp-2.8 {basic interpreter creation} {
 test interp-2.9 {basic interpreter creation} {
     interp create -safe -- -froboz1
 } -froboz1
-test interp-2.10 {basic interpreter creation} {
+test interp-2.10 {basic interpreter creation} -setup {
+    catch {interp create a}
+} -body {
     interp create {a x1}
     interp create {a x2}
     interp create {a x3} -safe
-} {a x3}
+} -result {a x3}
 test interp-2.11 {anonymous interps vs existing procs} {
     set x [interp create]
     regexp "interp(\[0-9]+)" $x dummy thenum
@@ -140,19 +144,26 @@ test interp-3.5 {testing interp exists and interp slaves} -body {
 test interp-3.6 {testing interp exists and interp slaves} {
     interp exists
 } 1
-test interp-3.7 {testing interp exists and interp slaves} {
+test interp-3.7 {testing interp exists and interp slaves} -setup {
+    catch {interp create a}
+} -body {
     interp slaves
-} a
+} -result a
 test interp-3.8 {testing interp exists and interp slaves} -body {
     interp slaves a b c
 } -returnCodes error -result {wrong # args: should be "interp slaves ?path?"}
-test interp-3.9 {testing interp exists and interp slaves} {
+test interp-3.9 {testing interp exists and interp slaves} -setup {
+    catch {interp create a}
+} -body {
     interp create {a a2} -safe
     expr {"a2" in [interp slaves a]}
-} 1
-test interp-3.10 {testing interp exists and interp slaves} {
+} -result 1
+test interp-3.10 {testing interp exists and interp slaves} -setup {
+    catch {interp create a}
+    catch {interp create {a a2}}
+} -body {
     interp exists {a a2}
-} 1
+} -result 1
 
 # Part 3: Testing "interp delete"
 test interp-3.11 {testing interp delete} {
@@ -222,6 +233,7 @@ test interp-6.3 {testing eval} {
     a eval {proc foo {} {expr 3 + 5}}
     a eval foo
 } 8
+catch {a eval {proc foo {} {expr 3 + 5}}}
 test interp-6.4 {testing eval} {
     interp eval a foo
 } 8
@@ -230,6 +242,7 @@ test interp-6.5 {testing eval} {
     interp eval {a x2} {proc frob {} {expr 4 * 9}}
     interp eval {a x2} frob
 } 36
+catch {interp create {a x2}}
 test interp-6.6 {testing eval} -returnCodes error -body {
     interp eval {a x2} foo
 } -result {invalid command name "foo"}
@@ -243,9 +256,11 @@ proc in_master {args} {
 test interp-7.1 {testing basic alias creation} {
     a alias foo in_master
 } foo
+catch {a alias foo in_master}
 test interp-7.2 {testing basic alias creation} {
     a alias bar in_master a1 a2 a3
 } bar
+catch {a alias bar in_master a1 a2 a3}
 # Test 6.3 has been deleted.
 test interp-7.3 {testing basic alias creation} {
     a alias foo
@@ -476,9 +491,13 @@ test interp-13.4 {testing issafe arg checking} {
 } {1 {wrong # args: should be "a issafe"}}
 
 # part 14: testing interp aliases
-test interp-14.1 {testing interp aliases} {
-    interp aliases
-} ""
+test interp-14.1 {testing interp aliases} -setup {
+    interp create abc
+} -body {
+    interp eval abc {interp aliases}
+} -cleanup {
+    interp delete abc
+} -result ""
 test interp-14.2 {testing interp aliases} {
     catch {interp delete a}
     interp create a
index 6b6ad6d..e2a05dc 100644 (file)
@@ -44,6 +44,7 @@ testConstraint testfevent       [llength [info commands testfevent]]
 testConstraint testchannelevent [llength [info commands testchannelevent]]
 testConstraint testmainthread   [llength [info commands testmainthread]]
 testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+testConstraint testobj         [llength [info commands testobj]]
 
 # You need a *very* special environment to do some tests.  In
 # particular, many file systems do not support large-files...
@@ -4285,6 +4286,13 @@ test io-33.4 {Tcl_Gets with long line} {
     close $f
     set x
 } {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+set f [open $path(test3) w]
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+close $f
 test io-33.5 {Tcl_Gets with long line} {
     set f [open $path(test3)]
     set x [gets $f y]
@@ -7141,7 +7149,12 @@ test io-52.10 {TclCopyChannel & encodings} {fcopy} {
 
     file size $path(utf8-fcopy.txt)
 } 5
-test io-52.11 {TclCopyChannel & encodings} {fcopy} {
+test io-52.11 {TclCopyChannel & encodings} -setup {
+    set out [open $path(utf8-fcopy.txt) w]
+    fconfigure $out -encoding utf-8 -translation lf
+    puts $out "\u0410\u0410"
+    close $out
+} -constraints {fcopy} -body {
     # binary to encoding => the input has to be
     # in utf-8 to make sense to the encoder
 
@@ -7157,7 +7170,7 @@ test io-52.11 {TclCopyChannel & encodings} {fcopy} {
     close $out
 
     file size $path(kyrillic.txt)
-} 3
+} -result 3
 
 test io-52.12 {coverage of -translation auto} {
     file delete $path(test1) $path(test2)
@@ -8626,6 +8639,24 @@ test io-73.5 {effect of eof on encoding end flags} -setup {
     removeFile io-73.5
 } -result [list 1 1 more\u00a0data 1]
 
+test io-74.1 {[104f2885bb] improper cache validity check} -setup {
+    set fn [makeFile {} io-74.1]
+    set rfd [open $fn r]
+    testobj freeallvars
+    interp create slave
+} -constraints testobj -body {
+    teststringobj set 1 [string range $rfd 0 end]
+    read [teststringobj get 1]         
+    testobj duplicate 1 2
+    interp transfer {} $rfd slave
+    catch {read [teststringobj get 1]}
+    read [teststringobj get 2]         
+} -cleanup {
+    interp delete slave
+    testobj freeallvars
+    removeFile io-74.1
+} -returnCodes error -match glob -result {can not find channel named "*"}
+
 # ### ### ### ######### ######### #########
 
 # cleanup
index 9536271..7c4b47f 100644 (file)
@@ -124,9 +124,11 @@ test load-3.2 {error in _Init procedure, slave interpreter} \
 test load-4.1 {reloading package into same interpreter} [list $dll $loaded] {
     list [catch {load [file join $testDir pkga$ext] pkga} msg] $msg
 } {0 {}}
-test load-4.2 {reloading package into same interpreter} [list $dll $loaded] {
-    list [catch {load [file join $testDir pkga$ext] pkgb} msg] $msg
-} [list 1 "file \"[file join $testDir pkga$ext]\" is already loaded for package \"Pkga\""]
+test load-4.2 {reloading package into same interpreter} -setup {
+    catch {load [file join $testDir pkga$ext] pkga}
+} -constraints [list $dll $loaded] -returnCodes error -body {
+    load [file join $testDir pkga$ext] pkgb
+} -result "file \"[file join $testDir pkga$ext]\" is already loaded for package \"Pkga\""
 
 test load-5.1 {file name not specified and no static package: pick default} \
        [list $dll $loaded] {
@@ -169,26 +171,40 @@ test load-7.3 {Tcl_StaticPackage procedure} [list teststaticpkg] {
     load {} More
     set x
 } {not loaded}
-test load-7.4 {Tcl_StaticPackage procedure, redundant calls} \
-    [list teststaticpkg $dll $loaded] {
-       teststaticpkg Double 0 1
-       teststaticpkg Double 0 1
-       info loaded
-    } [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] $alreadyTotalLoaded]
+catch {load [file join $testDir pkga$ext] pkga}
+catch {load [file join $testDir pkgb$ext] pkgb}
+catch {load [file join $testDir pkge$ext] pkge}
+set currentRealPackages [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]]
+test load-7.4 {Tcl_StaticPackage procedure, redundant calls} -setup {
+    teststaticpkg Test 1 0
+    teststaticpkg Another 0 0
+    teststaticpkg More 0 1
+} -constraints [list teststaticpkg $dll $loaded] -body {
+    teststaticpkg Double 0 1
+    teststaticpkg Double 0 1
+    info loaded
+} -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]
 
+teststaticpkg Test 1 1
+teststaticpkg Another 0 1
+teststaticpkg More 0 1
+teststaticpkg Double 0 1
 test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
-    info loaded
-} [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] $alreadyTotalLoaded]
-test load-8.2 {TclGetLoadedPackages procedure} [list teststaticpkg] {
-    list [catch {info loaded gorp} msg] $msg
-} {1 {could not find interpreter "gorp"}}
-test load-8.3 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
-    list [info loaded {}] [info loaded child]
-} [list [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]]
+    lsort -index 1 [info loaded]
+} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]]
+test load-8.2 {TclGetLoadedPackages procedure} -body {
+    info loaded gorp
+} -returnCodes error -result {could not find interpreter "gorp"}
+test load-8.3a {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+    lsort -index 1 [info loaded {}]
+} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]]
+test load-8.3b {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+    lsort -index 1 [info loaded child]
+} [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]]
 test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded teststaticpkg] {
     load [file join $testDir pkgb$ext] pkgb
-    list [info loaded {}] [lsort [info commands pkgb_*]]
-} [list [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] {pkgb_demo pkgb_sub pkgb_unsafe}]
+    list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]]
+} [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}]
 interp delete child
 
 test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} \
index e66a331..d7f8226 100644 (file)
@@ -98,7 +98,12 @@ test lreplace-1.26 {lreplace command} {
         [set foo [lreplace $foo end end]] \
         [set foo [lreplace $foo end end]]
 } {a {} {}}
-
+test lreplace-1.27 {lreplace command} {
+    lreplace x 1 1
+} x
+test lreplace-1.28 {lreplace command} {
+    lreplace x 1 1 y
+} {x y}
 
 test lreplace-2.1 {lreplace errors} {
     list [catch lreplace msg] $msg
@@ -119,8 +124,8 @@ test lreplace-2.6 {lreplace errors} {
     list [catch {lreplace x 3 2} msg] $msg
 } {1 {list doesn't contain element 3}}
 test lreplace-2.7 {lreplace errors} {
-    list [catch {lreplace x 1 1} msg] $msg
-} {1 {list doesn't contain element 1}}
+    list [catch {lreplace x 2 2} msg] $msg
+} {1 {list doesn't contain element 2}}
 
 test lreplace-3.1 {lreplace won't modify shared argument objects} {
     proc p {} {
@@ -181,6 +186,49 @@ test lreplace-4.11 {lreplace end index first} {
 test lreplace-4.12 {lreplace end index first} {
     lreplace {0 1 2 3 4} end-2 2 a b c
 } {0 1 a b c 3 4}
+test lreplace-4.13 {lreplace empty list} {
+    lreplace {} 1 1 1
+} 1
+test lreplace-4.14 {lreplace empty list} {
+    lreplace {} 2 2 2
+} 2
+
+test lreplace-5.1 {compiled lreplace: Bug 47ac84309b} {
+    apply {x {
+       lreplace $x end 0
+    }} {a b c}
+} {a b c}
+test lreplace-5.2 {compiled lreplace: Bug 47ac84309b} {
+    apply {x {
+       lreplace $x end 0 A
+    }} {a b c}
+} {a b A c}
+
+# Testing for compiled behaviour. Far too many variations to check with
+# spelt-out tests. Note that this *just* checks whether the compiled version
+# and the interpreted version are the same, not whether the interpreted
+# version is correct.
+apply {{} {
+    set lss     {{} {a} {a b c} {a b c d}}
+    set ins     {{} A {A B}}
+    set idxs    {-2 -1 0 1 2 3 end-3 end-2 end-1 end end+1 end+2}
+    set lreplace lreplace
+
+    foreach ls $lss {
+       foreach a $idxs {
+           foreach b $idxs {
+               foreach i $ins {
+                   set expected [list [catch {$lreplace $ls $a $b {*}$i} m] $m]
+                   set tester [list lreplace $ls $a $b {*}$i]
+                   set script [list catch $tester m]
+                   set script "list \[$script\] \$m"
+                   test lreplace-6.[incr n] {lreplace battery} \
+                       [list apply [list {} $script]] $expected
+               }
+           }
+       }
+    }
+}}
 \f
 # cleanup
 catch {unset foo}
index 8647f9c..ae35272 100644 (file)
@@ -68,6 +68,7 @@ namespace eval ::msgcat::test {
                set result c
            }
        }
+\f
        test msgcat-0.$count [list \
            locale initialization from environment variables $setVars \
        ] -setup {
@@ -973,7 +974,10 @@ namespace eval ::msgcat::test {
     }
     set bgerrorsaved [interp bgerror {}]
     interp bgerror {} [namespace code callbackproc]
-    
+
+    variable locale
+    if {![info exist locale]} { set locale [mclocale] }
+
        test msgcat-14.1 {invokation loadcmd} -setup {
            mcforgetpackage
            mclocale $locale
@@ -1068,7 +1072,7 @@ namespace eval ::msgcat::test {
            mc k1
        } -returnCodes 1\
        -result {fail}
-
+\f
     interp bgerror {} $bgerrorsaved
 
     cleanupTests
@@ -1076,3 +1080,6 @@ namespace eval ::msgcat::test {
 namespace delete ::msgcat::test
 return
 
+# Local Variables:
+# mode: tcl
+# End:
index 1d8ba31..1d6a805 100644 (file)
@@ -57,6 +57,12 @@ test namespace-old-1.9 {add elements to a namespace} {
         }
     }
 } {}
+namespace eval test_ns_simple {
+    variable test_ns_x 0
+    proc test {test_ns_x} {
+       return "test: $test_ns_x"
+    }
+}
 test namespace-old-1.10 {commands in a namespace} {
     namespace eval test_ns_simple { info commands [namespace current]::*}
 } {::test_ns_simple::test}
@@ -74,6 +80,12 @@ test namespace-old-1.13 {add to an existing namespace} {
         }
     }
 } ""
+namespace eval test_ns_simple {
+    variable test_ns_y 123
+    proc _backdoor {cmd} {
+       eval $cmd
+    }
+}
 test namespace-old-1.14 {commands in a namespace} {
     lsort [namespace eval test_ns_simple {info commands [namespace current]::*}]
 } {::test_ns_simple::_backdoor ::test_ns_simple::test}
@@ -128,6 +140,8 @@ test namespace-old-1.26 {namespace qualifiers are okay after $'s} {
 test namespace-old-1.27 {can create commands with null names} {
     proc test_ns_simple:: {args} {return $args}
 } {}
+# Redeclare; later tests depend on it
+proc test_ns_simple:: {args} {return $args}
 
 # -----------------------------------------------------------------------
 # TEST: using "info" in namespace contexts
@@ -212,6 +226,11 @@ test namespace-old-4.3 {command "namespace delete" doesn't support patterns} {
     }
     list [catch $cmd msg] $msg
 } {1 {unknown namespace "ns*" in namespace delete command}}
+namespace eval test_ns_delete {
+    namespace eval ns1 {}
+    namespace eval ns2 {}
+    namespace eval another {}
+}
 test namespace-old-4.4 {command "namespace delete" handles multiple args} {
     set cmd {
         namespace eval test_ns_delete {
@@ -256,6 +275,24 @@ test namespace-old-5.3 {namespace qualifiers work in namespace command} {
          [namespace eval test_ns_hier1::test_ns_hier2 {namespace current}] \
          [namespace eval ::test_ns_hier1::test_ns_hier2 {namespace current}]
 } {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2}
+set ::test_ns_var_global "var in ::"
+proc test_ns_cmd_global {} {return "cmd in ::"}
+namespace eval test_ns_hier1 {
+    variable test_ns_var_hier1 "particular to hier1"
+    proc test_ns_cmd_hier1 {} {return "particular to hier1"}
+    variable test_ns_level 1
+    proc test_ns_show {} {return "[namespace current]: 1"}
+    namespace eval test_ns_hier2 {
+       variable test_ns_var_hier2 "particular to hier2"
+       proc test_ns_cmd_hier2 {} {return "particular to hier2"}
+       variable test_ns_level 2
+        proc test_ns_show {} {return "[namespace current]: 2"}
+       namespace eval test_ns_hier3a {}
+       namespace eval test_ns_hier3b {}
+    }
+    namespace eval test_ns_hier2a {}
+    namespace eval test_ns_hier2b {}
+}
 test namespace-old-5.4 {nested namespaces can access global namespace} {
     list [namespace eval test_ns_hier1 {set test_ns_var_global}] \
          [namespace eval test_ns_hier1 {test_ns_cmd_global}] \
@@ -331,16 +368,12 @@ test namespace-old-5.21 {querying namespace parent for explicit namespace} {
 # -----------------------------------------------------------------------
 # TEST: name resolution and caching
 # -----------------------------------------------------------------------
+set trigger {namespace eval test_ns_cache2 {namespace current}}
+set trigger2 {namespace eval test_ns_cache2::test_ns_cache3 {namespace current}}
 test namespace-old-6.1 {relative ns names only looked up in current ns} {
     namespace eval test_ns_cache1 {}
     namespace eval test_ns_cache2 {}
     namespace eval test_ns_cache2::test_ns_cache3 {}
-    set trigger {
-        namespace eval test_ns_cache2 {namespace current}
-    }
-    set trigger2 {
-        namespace eval test_ns_cache2::test_ns_cache3 {namespace current}
-    }
     list [namespace eval test_ns_cache1 $trigger] \
          [namespace eval test_ns_cache1 $trigger2]
 } {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
@@ -354,20 +387,19 @@ test namespace-old-6.3 {relative ns names only looked up in current ns} {
     list [namespace eval test_ns_cache1 $trigger] \
          [namespace eval test_ns_cache1 $trigger2]
 } {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+namespace eval test_ns_cache1::test_ns_cache2 {}
 test namespace-old-6.4 {relative ns names only looked up in current ns} {
     namespace delete test_ns_cache1::test_ns_cache2
     list [namespace eval test_ns_cache1 $trigger] \
          [namespace eval test_ns_cache1 $trigger2]
 } {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+namespace eval test_ns_cache1 {
+    proc trigger {} {test_ns_cache_cmd}
+}
 test namespace-old-6.5 {define test commands} {
     proc test_ns_cache_cmd {} {
         return "global version"
     }
-    namespace eval test_ns_cache1 {
-        proc trigger {} {
-            test_ns_cache_cmd
-        }
-    }
     test_ns_cache1::trigger
 } {global version}
 test namespace-old-6.6 {one-level check for command shadowing} {
@@ -376,24 +408,36 @@ test namespace-old-6.6 {one-level check for command shadowing} {
     }
     test_ns_cache1::trigger
 } {cache1 version}
-test namespace-old-6.7 {renaming commands changes command epoch} {
-    namespace eval test_ns_cache1 {
-        rename test_ns_cache_cmd test_ns_new
+proc test_ns_cache_cmd {} {
+    return "global version"
+}
+test namespace-old-6.7 {renaming commands changes command epoch} -setup {
+    proc test_ns_cache1::test_ns_cache_cmd {} {
+        return "cache1 version"
     }
-    test_ns_cache1::trigger
-} {global version}
-test namespace-old-6.8 {renaming back handles shadowing} {
-    namespace eval test_ns_cache1 {
-        rename test_ns_new test_ns_cache_cmd
+} -body {
+    list [test_ns_cache1::trigger] \
+       [namespace eval test_ns_cache1 {rename test_ns_cache_cmd test_ns_new}]\
+       [test_ns_cache1::trigger]
+} -result {{cache1 version} {} {global version}}
+test namespace-old-6.8 {renaming back handles shadowing} -setup {
+    proc test_ns_cache1::test_ns_new {} {
+        return "cache1 version"
     }
-    test_ns_cache1::trigger
-} {cache1 version}
-test namespace-old-6.9 {deleting commands changes command epoch} {
-    namespace eval test_ns_cache1 {
-        rename test_ns_cache_cmd ""
+} -body {
+    list [test_ns_cache1::trigger] \
+       [namespace eval test_ns_cache1 {rename test_ns_new test_ns_cache_cmd}]\
+       [test_ns_cache1::trigger]
+} -result {{global version} {} {cache1 version}}
+test namespace-old-6.9 {deleting commands changes command epoch} -setup {
+    proc test_ns_cache1::test_ns_cache_cmd {} {
+        return "cache1 version"
     }
-    test_ns_cache1::trigger
-} {global version}
+} -body {
+    list [test_ns_cache1::trigger] \
+       [namespace eval test_ns_cache1 {rename test_ns_cache_cmd ""}] \
+       [test_ns_cache1::trigger]
+} -result {{cache1 version} {} {global version}}
 test namespace-old-6.10 {define test namespaces} {
     namespace eval test_ns_cache2 {
         proc test_ns_cache_cmd {} {
@@ -412,6 +456,12 @@ test namespace-old-6.10 {define test namespaces} {
     }
     list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
 } {{global cache2 version} {global version}}
+namespace eval test_ns_cache1 {
+    proc trigger {} { test_ns_cache2::test_ns_cache_cmd }
+    namespace eval test_ns_cache2 {
+       proc trigger {} { test_ns_cache_cmd }
+    }
+}
 test namespace-old-6.11 {commands affect all parent namespaces} {
     proc test_ns_cache1::test_ns_cache2::test_ns_cache_cmd {} {
         return "cache2 version"
@@ -423,18 +473,22 @@ test namespace-old-6.12 {define test variables} {
     set trigger {set test_ns_cache_var}
     namespace eval test_ns_cache1 $trigger
 } {global version}
+    set trigger {set test_ns_cache_var}
 test namespace-old-6.13 {one-level check for variable shadowing} {
     namespace eval test_ns_cache1 {
         variable test_ns_cache_var "cache1 version"
     }
     namespace eval test_ns_cache1 $trigger
 } {cache1 version}
+variable ::test_ns_cache_var "global version"
 test namespace-old-6.14 {deleting variables changes variable epoch} {
     namespace eval test_ns_cache1 {
-        unset test_ns_cache_var
+        variable test_ns_cache_var "cache1 version"
     }
-    namespace eval test_ns_cache1 $trigger
-} {global version}
+    list [namespace eval test_ns_cache1 $trigger] \
+       [namespace eval test_ns_cache1 {unset test_ns_cache_var}] \
+       [namespace eval test_ns_cache1 $trigger]
+} {{cache1 version} {} {global version}}
 test namespace-old-6.15 {define test namespaces} {
     namespace eval test_ns_cache2 {
         variable test_ns_cache_var "global cache2 version"
@@ -443,6 +497,7 @@ test namespace-old-6.15 {define test namespaces} {
     list [namespace eval test_ns_cache1 $trigger2] \
          [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
 } {{global cache2 version} {global version}}
+set trigger2 {set test_ns_cache2::test_ns_cache_var}
 test namespace-old-6.16 {public variables affect all parent namespaces} {
     variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
     list [namespace eval test_ns_cache1 $trigger2] \
@@ -467,6 +522,7 @@ test namespace-old-6.19 {querying:  namespace which -command} {
 test namespace-old-6.20 {command "namespace which" may not find commands} {
     namespace eval test_ns_cache1 {namespace which -command xyzzy}
 } {}
+variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
 test namespace-old-6.21 {querying:  namespace which -variable} {
     namespace eval test_ns_cache1::test_ns_cache2 {
         namespace which -variable test_ns_cache_var
@@ -493,6 +549,18 @@ test namespace-old-7.1 {define test namespace} {
         }
     }
 } {}
+namespace eval test_ns_uplevel {
+    variable x 0
+    variable y 1
+    proc show_vars {num} {
+       return [uplevel $num {info vars}]
+    }
+    proc test_uplevel {num} {
+       set a 0
+       set b 1
+       namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
+    }
+}
 test namespace-old-7.2 {uplevel can access namespace call frame} {
     list [expr {"x" in [test_ns_uplevel::test_uplevel 1]}] \
          [expr {"y" in [test_ns_uplevel::test_uplevel 1]}]
@@ -526,6 +594,17 @@ test namespace-old-7.8 {namespaces are included in the call stack} {
         }
     }
 } {}
+namespace eval test_ns_upvar {
+    variable scope "test_ns_upvar"
+    proc show_val {var num} {
+       upvar $num $var x
+       return $x
+    }
+    proc test_upvar {num} {
+       set scope "test_ns_upvar::test_upvar"
+       namespace eval ::test_ns_upvar " return \[show_val scope $num\] "
+    }
+}
 test namespace-old-7.9 {upvar can access namespace call frame} {
     test_ns_upvar::test_upvar 1
 } {test_ns_upvar}
@@ -581,6 +660,15 @@ test namespace-old-9.3 {define test namespaces for import} {
     }
     lsort [info commands test_ns_export::*]
 } {::test_ns_export::cmd1 ::test_ns_export::cmd2 ::test_ns_export::cmd3 ::test_ns_export::cmd4 ::test_ns_export::cmd5 ::test_ns_export::cmd6}
+namespace eval test_ns_export {
+    namespace export cmd1 cmd2 cmd3
+    proc cmd1 {args} {return "cmd1: $args"}
+    proc cmd2 {args} {return "cmd2: $args"}
+    proc cmd3 {args} {return "cmd3: $args"}
+    proc cmd4 {args} {return "cmd4: $args"}
+    proc cmd5 {args} {return "cmd5: $args"}
+    proc cmd6 {args} {return "cmd6: $args"}
+}
 test namespace-old-9.4 {check export status} {
     set x ""
     namespace eval test_ns_import {
@@ -592,6 +680,10 @@ test namespace-old-9.4 {check export status} {
     }
     set x
 } {::test_ns_import::cmd1 ::test_ns_import::cmd2 ::test_ns_import::cmd3}
+namespace eval test_ns_import {
+    namespace export cmd1 cmd2
+    namespace import ::test_ns_export::*
+}
 test namespace-old-9.5 {empty import list in "namespace import" command} {
     namespace eval test_ns_import_empty {
        namespace import ::test_ns_export::*
@@ -615,6 +707,7 @@ test namespace-old-9.8 {only exported commands are imported} {
     namespace import test_ns_import::cmd*
     set x [lsort [info commands cmd*]]
 } {cmd1 cmd2}
+namespace import test_ns_import::cmd*
 test namespace-old-9.9 {imported commands work just the same as original} {
     list [cmd1 test 1 2 3] [test_ns_import::cmd1 test 4 5 6]
 } {{cmd1: test 1 2 3} {cmd1: test 4 5 6}}
@@ -629,10 +722,19 @@ test namespace-old-9.10 {commands can be imported from many namespaces} {
     namespace import test_ns_import2::*
     lsort [concat [info commands cmd*] [info commands ncmd*]]
 } {cmd1 cmd2 ncmd ncmd1 ncmd2}
+namespace eval test_ns_import2 {
+    namespace export ncmd ncmd1 ncmd2
+    proc ncmd  {args} {return "ncmd: $args"}
+    proc ncmd1 {args} {return "ncmd1: $args"}
+    proc ncmd2 {args} {return "ncmd2: $args"}
+    proc ncmd3 {args} {return "ncmd3: $args"}
+}
+namespace import test_ns_import2::*
 test namespace-old-9.11 {imported commands can be removed by deleting them} {
     rename cmd1 ""
     lsort [concat [info commands cmd*] [info commands ncmd*]]
 } {cmd2 ncmd ncmd1 ncmd2}
+catch { rename cmd1 "" }
 test namespace-old-9.12 {command "namespace forget" checks for valid namespaces} {
     list [catch {namespace forget xyzzy::*} msg] $msg
 } {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
@@ -653,6 +755,7 @@ test namespace-old-9.15 {existing commands can't be overwritten} {
          [cmd1 3 5]
 } {1 {can't import command "cmd1": already exists} 8}
 test namespace-old-9.16 {use "-force" option to override existing commands} {
+    proc cmd1 {x y} { return [expr $x+$y] }
     list [cmd1 3 5] \
          [namespace import -force test_ns_import::cmd?] \
          [cmd1 3 5]
@@ -711,10 +814,18 @@ test namespace-old-10.6 {with many args, each "scope" adds new args} {
     set sval [namespace eval test_ns_inscope {namespace code {one two}}]
     namespace code "$sval three"
 } {::namespace inscope ::test_ns_inscope {one two} three}
+namespace eval test_ns_inscope {
+    proc show {args} {
+       return "show: $args"
+    }
+}
 test namespace-old-10.7 {scoped commands work with eval} {
     set cref [namespace eval test_ns_inscope {namespace code show}]
     list [eval $cref "a" "b c" "d e f"]
 } {{show: a b c d e f}}
+namespace eval test_ns_inscope {
+    variable x "x-value"
+}
 test namespace-old-10.8 {scoped commands execute in namespace context} {
     set cref [namespace eval test_ns_inscope {
         namespace code {set x "some new value"}
index cded1f4..de7009d 100644 (file)
@@ -82,12 +82,14 @@ test namespace-4.2 {Tcl_PushCallFrame with isProcCallFrame=0} {
 test namespace-5.1 {Tcl_PopCallFrame, no vars} {
     namespace eval test_ns_1::blodge {}  ;# pushes then pops frame
 } {}
-test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} {
+test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} -setup {
+    namespace eval test_ns_1 {}
+} -body {
     proc test_ns_1::r {} {
         set a 123
     }
     test_ns_1::r   ;# pushes then pop's r's frame
-} {123}
+} -result {123}
 
 test namespace-6.1 {Tcl_CreateNamespace} {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
@@ -194,7 +196,6 @@ test namespace-7.7 {Bug 1655305} -setup {
     interp delete slave
 } -result {}
 
-
 test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
     catch {interp delete test_interp}
     interp create test_interp
@@ -303,15 +304,24 @@ test namespace-9.4 {Tcl_Import, simple import} {
     }
     test_ns_import::p
 } {cmd1: 123}
-test namespace-9.5 {Tcl_Import, RFE 1230597} {
+test namespace-9.5 {Tcl_Import, RFE 1230597} -setup {
+    namespace eval test_ns_import {}
+    namespace eval test_ns_export {}
+} -body {
     list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
-} {0 {}}
-test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} {
+} -result {0 {}}
+test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} -setup {
+    namespace eval test_ns_import {}
+    namespace eval ::test_ns_export {
+        proc cmd1 {args} {return "cmd1: $args"}
+       namespace export cmd1
+    }
+} -body {
     namespace eval test_ns_import {
         namespace import -force ::test_ns_export::*
         cmd1 555
     }
-} {cmd1: 555}
+} -result {cmd1: 555}
 test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
     namespace eval test_ns_export {
@@ -329,7 +339,6 @@ test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
          [test_ns_import::cmd1 g h i] \
          [test_ns_export::cmd1 j k l]
 } {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}
-
 test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
     namespace eval one {
        namespace export cmd
@@ -354,7 +363,6 @@ test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
 } -cleanup {
     namespace delete one two three
 } -match glob -result *::one::cmd
-
 test namespace-9.9 {Tcl_Import: Bug 1017299} -setup {
     namespace eval one {
        namespace export cmd
@@ -388,7 +396,13 @@ test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
         namespace forget ::test_ns_export::wombat
     }
 } {}
-test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} {
+test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} -setup {
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+} -body {
     namespace eval test_ns_import {
         namespace import ::test_ns_export::*
         proc p {} {return [cmd1 123]}
@@ -398,8 +412,7 @@ test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} {
         lappend l [info commands ::test_ns_import::*]
         lappend l [catch {cmd1 777} msg] $msg
     }
-} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
-
+} -result [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
 test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
     namespace eval origin {
        namespace export cmd
@@ -417,7 +430,6 @@ test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
 } -cleanup {
     namespace delete origin unrelated my
 }
-
 test namespace-10.5 {Tcl_ForgetImport: Bug 560297} -setup {
     namespace eval origin {
        namespace export cmd
@@ -433,7 +445,6 @@ test namespace-10.5 {Tcl_ForgetImport: Bug 560297} -setup {
 } -cleanup {
     namespace delete origin my
 } -returnCodes error -match glob -result *
-
 test namespace-10.6 {Tcl_ForgetImport: Bug 560297} -setup {
     namespace eval origin {
        namespace export cmd
@@ -450,7 +461,6 @@ test namespace-10.6 {Tcl_ForgetImport: Bug 560297} -setup {
 } -cleanup {
     namespace delete origin my your
 } -returnCodes error -match glob -result *
-
 test namespace-10.7 {Tcl_ForgetImport: Bug 560297} -setup {
     namespace eval origin {
        namespace export cmd
@@ -471,7 +481,6 @@ test namespace-10.7 {Tcl_ForgetImport: Bug 560297} -setup {
 } -cleanup {
     namespace delete origin link link2 my
 } -returnCodes error -match glob -result *
-
 test namespace-10.8 {Tcl_ForgetImport: Bug 560297} -setup {
     namespace eval origin {
        namespace export cmd
@@ -492,7 +501,6 @@ test namespace-10.8 {Tcl_ForgetImport: Bug 560297} -setup {
 } -cleanup {
     namespace delete origin link link2 my
 }
-
 test namespace-10.9 {Tcl_ForgetImport: Bug 560297} -setup {
     namespace eval origin {
        namespace export cmd
@@ -514,29 +522,47 @@ test namespace-10.9 {Tcl_ForgetImport: Bug 560297} -setup {
     namespace delete origin link link2 my
 } -returnCodes error -match glob -result *
 
-test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} {
+test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_export {
         namespace export cmd1
         proc cmd1 {args} {return "cmd1: $args"}
     }
     list [namespace origin set] [namespace origin test_ns_export::cmd1]
-} {::set ::test_ns_export::cmd1}
-test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} {
+} -result {::set ::test_ns_export::cmd1}
+test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+    }
+} -body {
     namespace eval test_ns_import1 {
         namespace import ::test_ns_export::*
         namespace export *
         proc p {} {namespace origin cmd1}
     }
     list [test_ns_import1::p] [namespace origin test_ns_import1::cmd1]
-} {::test_ns_export::cmd1 ::test_ns_export::cmd1}
-test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} {
+} -result {::test_ns_export::cmd1 ::test_ns_export::cmd1}
+test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+    }
+    namespace eval test_ns_import1 {
+        namespace import ::test_ns_export::*
+        namespace export *
+        proc p {} {namespace origin cmd1}
+    }
+} -body {
     namespace eval test_ns_import2 {
         namespace import ::test_ns_import1::*
         proc q {} {return [cmd1 123]}
     }
     list [test_ns_import2::q] [namespace origin test_ns_import2::cmd1]
-} {{cmd1: 123} ::test_ns_export::cmd1}
+} -result {{cmd1: 123} ::test_ns_export::cmd1}
 
 test namespace-12.1 {InvokeImportedCmd} {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
@@ -550,14 +576,23 @@ test namespace-12.1 {InvokeImportedCmd} {
     list [test_ns_import::cmd1]
 } {::test_ns_export}
 
-test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} {
+test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {namespace current}
+    }
+    namespace eval test_ns_import {
+        namespace import ::test_ns_export::*
+    }
+} -body {
     namespace eval test_ns_import {
         set l {}
         lappend l [info commands ::test_ns_import::*]
         namespace forget ::test_ns_export::cmd1
         lappend l [info commands ::test_ns_import::*]
     }
-} {::test_ns_import::cmd1 {}}
+} -result {::test_ns_import::cmd1 {}}
 test namespace-13.2 {DeleteImportedCmd, Bug a4494e28ed} {
     # Will panic if still buggy
     namespace eval src {namespace export foo; proc foo {} {}}
@@ -568,7 +603,7 @@ test namespace-13.2 {DeleteImportedCmd, Bug a4494e28ed} {
     namespace delete src
 } {}
 
-test namespace-14.1 {TclGetNamespaceForQualName, absolute names} {
+test namespace-14.1 {TclGetNamespaceForQualName, absolute names} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
     variable v 10
     namespace eval test_ns_1::test_ns_2 {
@@ -577,22 +612,41 @@ test namespace-14.1 {TclGetNamespaceForQualName, absolute names} {
     namespace eval test_ns_2 {
         variable v 30
     }
+} -body {
     namespace eval test_ns_1 {
         list $::v $::test_ns_2::v $::test_ns_1::test_ns_2::v \
                [lsort [namespace children :: test_ns_*]]
     }
-} [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
-test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} {
+} -result [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
+test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    variable v 10
+    namespace eval test_ns_1::test_ns_2 {
+        variable v 20
+    }
+    namespace eval test_ns_2 {
+        variable v 30
+    }
+} -body {
     namespace eval test_ns_1 {
         list [catch {set ::test_ns_777::v} msg] $msg \
              [catch {namespace children test_ns_777} msg] $msg
     }
-} {1 {can't read "::test_ns_777::v": no such variable} 1 {namespace "test_ns_777" not found in "::test_ns_1"}}
-test namespace-14.3 {TclGetNamespaceForQualName, relative names} {
+} -result {1 {can't read "::test_ns_777::v": no such variable} 1 {namespace "test_ns_777" not found in "::test_ns_1"}}
+test namespace-14.3 {TclGetNamespaceForQualName, relative names} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    variable v 10
+    namespace eval test_ns_1::test_ns_2 {
+        variable v 20
+    }
+    namespace eval test_ns_2 {
+        variable v 30
+    }
+} -body {
     namespace eval test_ns_1 {
         list $v $test_ns_2::v
     }
-} {10 20}
+} -result {10 20}
 test namespace-14.4 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
     namespace eval test_ns_1::test_ns_2 {
         namespace eval foo {}
@@ -619,57 +673,72 @@ test namespace-14.6 {TclGetNamespaceForQualName, relative ns names looked up onl
              [catch {namespace children test_ns_1} msg] $msg
     }
 } {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
-test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} {
+test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
+} -body {
     namespace children test_ns_1:::
-} {::test_ns_1::test_ns_2}
-test namespace-14.8 {TclGetNamespaceForQualName, ignore extra :s if ns} {
+} -result {::test_ns_1::test_ns_2}
+test namespace-14.8 {TclGetNamespaceForQualName, ignore extra :s if ns} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
+} -body {
     namespace children :::test_ns_1:::::test_ns_2:::
-} {::test_ns_1::test_ns_2::foo}
+} -result {::test_ns_1::test_ns_2::foo}
 test namespace-14.9 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
     set l {}
     lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
     namespace eval test_ns_1::test_ns_2 {variable {} 2525}
     lappend l [set test_ns_1::test_ns_2::]
 } {1 {can't read "test_ns_1::test_ns_2::": no such variable} 2525}
-test namespace-14.10 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
-    catch {unset test_ns_1::test_ns_2::}
+test namespace-14.10 {TclGetNamespaceForQualName, extra ::s are significant for vars} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
+    unset -nocomplain test_ns_1::test_ns_2::
     set l {}
+} -body {
     lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
     set test_ns_1::test_ns_2:: 314159
     lappend l [set test_ns_1::test_ns_2::]
-} {1 {can't read "test_ns_1::test_ns_2::": no such variable} 314159}
-test namespace-14.11 {TclGetNamespaceForQualName, extra ::s are significant for commands} {
+} -result {1 {can't read "test_ns_1::test_ns_2::": no such variable} 314159}
+test namespace-14.11 {TclGetNamespaceForQualName, extra ::s are significant for commands} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
     catch {rename test_ns_1::test_ns_2:: {}}
     set l {}
+} -body {
     lappend l [catch {test_ns_1::test_ns_2:: hello} msg] $msg
     proc test_ns_1::test_ns_2:: {args} {return "\{\}: $args"}
     lappend l [test_ns_1::test_ns_2:: hello]
-} {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}
-test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+} -result {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}
+test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_1 {
         variable {}
         set test_ns_1::(x) y
     }
     set test_ns_1::(x)
-} y
-test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} {
+} -result y
+test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
-    list [catch {namespace eval test_ns_1 {proc {} {} {}; namespace eval {} {}; {}}} msg] $msg
-} {1 {can't create namespace "": only global namespace can have empty name}}
+} -returnCodes error -body {
+    namespace eval test_ns_1 {
+       proc {} {} {}
+       namespace eval {} {}
+       {}
+    }
+} -result {can't create namespace "": only global namespace can have empty name}
 
-test namespace-15.1 {Tcl_FindNamespace, absolute name found} {
+test namespace-15.1 {Tcl_FindNamespace, absolute name found} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_delete {
         namespace eval test_ns_delete2 {}
         proc cmd {args} {namespace current}
     }
     list [namespace delete ::test_ns_delete::test_ns_delete2] \
          [namespace children ::test_ns_delete]
-} {{} {}}
-test namespace-15.2 {Tcl_FindNamespace, absolute name not found} {
-    list [catch {namespace delete ::test_ns_delete::test_ns_delete2} msg] $msg
-} {1 {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}}
+} -result {{} {}}
+test namespace-15.2 {Tcl_FindNamespace, absolute name not found} -body {
+    namespace delete ::test_ns_delete::test_ns_delete2
+} -returnCodes error -result {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}
 test namespace-15.3 {Tcl_FindNamespace, relative name found} {
     namespace eval test_ns_delete {
         namespace eval test_ns_delete2 {}
@@ -685,17 +754,24 @@ test namespace-15.4 {Tcl_FindNamespace, relative name not found} {
     }
 } {1 {unknown namespace "test_ns_delete2" in namespace delete command}}
 
-test namespace-16.1 {Tcl_FindCommand, absolute name found} {
+test namespace-16.1 {Tcl_FindCommand, absolute name found} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_1 {
         proc cmd {args} {return "[namespace current]::cmd: $args"}
         variable v "::test_ns_1::cmd"
         eval $v one
     }
-} {::test_ns_1::cmd: one}
-test namespace-16.2 {Tcl_FindCommand, absolute name found} {
+} -result {::test_ns_1::cmd: one}
+test namespace-16.2 {Tcl_FindCommand, absolute name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd {args} {return "[namespace current]::cmd: $args"}
+        variable v "::test_ns_1::cmd"
+    }
+} -body {
     eval $test_ns_1::v two
-} {::test_ns_1::cmd: two}
+} -result {::test_ns_1::cmd: two}
 test namespace-16.3 {Tcl_FindCommand, absolute name not found} {
     namespace eval test_ns_1 {
         variable v2 "::test_ns_1::ladidah"
@@ -724,11 +800,16 @@ test namespace-16.7 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
 catch {rename unknown {}}
 catch {rename unknown.old unknown}
 
-test namespace-16.8 {Tcl_FindCommand, relative name found} {
+test namespace-16.8 {Tcl_FindCommand, relative name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd {args} {return "[namespace current]::cmd: $args"}
+    }
+} -body {
     namespace eval test_ns_1 {
         cmd a b c
     }
-} {::test_ns_1::cmd: a b c}
+} -result {::test_ns_1::cmd: a b c}
 test namespace-16.9 {Tcl_FindCommand, relative name found} -body {
     proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
     namespace eval test_ns_1 {
@@ -750,20 +831,22 @@ test namespace-16.10 {Tcl_FindCommand, relative name found, only look in current
 } -cleanup {
     catch {rename cmd2 {}}
 } -result {::::cmd2: a b c}
-test namespace-16.11 {Tcl_FindCommand, relative name not found} {
+test namespace-16.11 {Tcl_FindCommand, relative name not found} -body {
     namespace eval test_ns_1 {
-       list [catch {cmd3 a b c} msg] $msg
+       cmd3 a b c
     }
-} {1 {invalid command name "cmd3"}}
+} -returnCodes error -result {invalid command name "cmd3"}
 
-catch {unset x}
-test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} {
+unset -nocomplain x
+test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     set x 314159
     namespace eval test_ns_1 {
         set ::x
     }
-} {314159}
+} -result {314159}
+variable ::x 314159
 test namespace-17.2 {Tcl_FindNamespaceVar, absolute name found} {
     namespace eval test_ns_1 {
         variable x 777
@@ -778,46 +861,54 @@ test namespace-17.3 {Tcl_FindNamespaceVar, absolute name found} {
         set ::test_ns_1::test_ns_2::x
     }
 } {1111}
-test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} {
+test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} -body {
     namespace eval test_ns_1 {
         namespace eval test_ns_2 {
             variable x 1111
         }
-        list [catch {set ::test_ns_1::test_ns_2::y} msg] $msg
+        set ::test_ns_1::test_ns_2::y
     }
-} {1 {can't read "::test_ns_1::test_ns_2::y": no such variable}}
-test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} {
+} -returnCodes error -result {can't read "::test_ns_1::test_ns_2::y": no such variable}
+test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} -setup {
+    namespace eval ::test_ns_1::test_ns_2 {}
+} -body {
     namespace eval test_ns_1 {
         namespace eval test_ns_3 {
             variable ::test_ns_1::test_ns_2::x 2222
         }
     }
     set ::test_ns_1::test_ns_2::x
-} {2222}
-test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} {
+} -result {2222}
+test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} -setup {
+    namespace eval test_ns_1 {
+        variable x 777
+    }
+} -body {
     namespace eval test_ns_1 {
         set x
     }
-} {777}
+} -result {777}
 test namespace-17.7 {Tcl_FindNamespaceVar, relative name found} {
     namespace eval test_ns_1 {
+       variable x 777
         unset x
         set x  ;# must be global x now
     }
 } {314159}
-test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} {
+test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} -body {
     namespace eval test_ns_1 {
-        list [catch {set wuzzat} msg] $msg
+        set wuzzat
     }
-} {1 {can't read "wuzzat": no such variable}}
+} -returnCodes error -result {can't read "wuzzat": no such variable}
 test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
     namespace eval test_ns_1 {
         variable a hello
     }
     set test_ns_1::a
 } {hello}
-test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} {
+test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} -setup {
     namespace eval test_ns_1 {}
+} -body {
     proc test_ns {} {
        set ::test_ns_1::a 0
     }
@@ -828,14 +919,15 @@ test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} {
     namespace eval test_ns_1 set a 1
     namespace delete test_ns_1
     return $a
-} 1
+} -result 1
 catch {unset a}
 catch {unset x}
 
 catch {unset l}
 catch {rename foo {}}
-test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} {
+test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     proc foo {} {return "global foo"}
     namespace eval test_ns_1 {
         proc trigger {} {
@@ -849,7 +941,7 @@ test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadow
         proc foo {} {return "foo in test_ns_1"}
     }
     lappend l [test_ns_1::trigger]
-} {{global foo} {foo in test_ns_1}}
+} -result {{global foo} {foo in test_ns_1}}
 test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shadowing} {
     namespace eval test_ns_2 {
         proc foo {} {return "foo in ::test_ns_2"}
@@ -873,22 +965,31 @@ test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shado
 catch {unset l}
 catch {rename foo {}}
 
-test namespace-19.1 {GetNamespaceFromObj, global name found} {
+test namespace-19.1 {GetNamespaceFromObj, global name found} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_1::test_ns_2 {}
     namespace children ::test_ns_1
-} {::test_ns_1::test_ns_2}
-test namespace-19.2 {GetNamespaceFromObj, relative name found} {
+} -result {::test_ns_1::test_ns_2}
+test namespace-19.2 {GetNamespaceFromObj, relative name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
     namespace eval test_ns_1 {
         namespace children test_ns_2
     }
-} {}
-test namespace-19.3 {GetNamespaceFromObj, name not found} -body {
+} -result {}
+test namespace-19.3 {GetNamespaceFromObj, name not found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_1 {
         namespace children test_ns_99
     }
 } -returnCodes error -result {namespace "test_ns_99" not found in "::test_ns_1"}
-test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} {
+test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
     namespace eval test_ns_1 {
         proc foo {} {
             return [namespace children test_ns_2]
@@ -900,7 +1001,7 @@ test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} {
     namespace delete test_ns_1::test_ns_2
     namespace eval test_ns_1::test_ns_2::test_ns_3 {}
     lappend l [test_ns_1::foo]
-} {{} ::test_ns_1::test_ns_2::test_ns_3}
+} -result {{} ::test_ns_1::test_ns_2::test_ns_3}
 
 test namespace-20.1 {Tcl_NamespaceObjCmd, bad subcommand} {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
@@ -913,24 +1014,34 @@ test namespace-20.3 {Tcl_NamespaceObjCmd, abbreviations are okay} {
     namespace ch :: test_ns_*
 } {}
 
-test namespace-21.1 {NamespaceChildrenCmd, no args} {
+test namespace-21.1 {NamespaceChildrenCmd, no args} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_1::test_ns_2 {}
-    expr {[string first ::test_ns_1 [namespace children]] != -1}
-} {1}
-test namespace-21.2 {NamespaceChildrenCmd, no args} {
+    expr {"::test_ns_1" in [namespace children]}
+} -result {1}
+test namespace-21.2 {NamespaceChildrenCmd, no args} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
     namespace eval test_ns_1 {
         namespace children
     }
-} {::test_ns_1::test_ns_2}
-test namespace-21.3 {NamespaceChildrenCmd, ns name given} {
+} -result {::test_ns_1::test_ns_2}
+test namespace-21.3 {NamespaceChildrenCmd, ns name given} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
     namespace children ::test_ns_1
-} {::test_ns_1::test_ns_2}
-test namespace-21.4 {NamespaceChildrenCmd, ns name given} {
+} -result {::test_ns_1::test_ns_2}
+test namespace-21.4 {NamespaceChildrenCmd, ns name given} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
     namespace eval test_ns_1 {
         namespace children test_ns_2
     }
-} {}
+} -result {}
 test namespace-21.5 {NamespaceChildrenCmd, too many args} {
     namespace eval test_ns_1 {
         list [catch {namespace children test_ns_2 xxx yyy} msg] $msg
@@ -940,10 +1051,13 @@ test namespace-21.6 {NamespaceChildrenCmd, glob-style pattern given} {
     namespace eval test_ns_1::test_ns_foo {}
     namespace children test_ns_1 *f*
 } {::test_ns_1::test_ns_foo}
-test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} {
+test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
     namespace eval test_ns_1::test_ns_foo {}
     lsort [namespace children test_ns_1 test*]
-} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_foo}]
+} -result {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_foo}
 test namespace-21.8 {NamespaceChildrenCmd, trivial pattern starting with ::} {
     namespace eval test_ns_1 {}
     namespace children [namespace current] [fq test_ns_1]
@@ -1038,15 +1152,25 @@ test namespace-25.3 {NamespaceEvalCmd, new namespace} {
     }
     test_ns_1::p
 } {314159}
-test namespace-25.4 {NamespaceEvalCmd, existing namespace} {
+test namespace-25.4 {NamespaceEvalCmd, existing namespace} -setup {
+    namespace eval test_ns_1 {
+        variable v 314159
+        proc p {} {
+            variable v
+            return $v
+        }
+    }
+} -body {
     namespace eval test_ns_1 {
         proc q {} {return [expr {[p]+1}]}
     }
     test_ns_1::q
-} {314160}
-test namespace-25.5 {NamespaceEvalCmd, multiple args} {
+} -result {314160}
+test namespace-25.5 {NamespaceEvalCmd, multiple args} -setup {
+    namespace eval test_ns_1 {variable v 314159}
+} -body {
     namespace eval test_ns_1 "set" "v"
-} {314159}
+} -result {314159}
 test namespace-25.6 {NamespaceEvalCmd, error in eval'd script} {
     list [catch {namespace eval test_ns_1 {xxxx}} msg] $msg $::errorInfo
 } {1 {invalid command name "xxxx"} {invalid command name "xxxx"
@@ -1097,21 +1221,50 @@ test namespace-26.4 {NamespaceExportCmd, one pattern} {
     }
     list [info commands test_ns_2::*] [test_ns_2::cmd1 hello]
 } {::test_ns_2::cmd1 {cmd1: hello}}
-test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} {
+test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
     namespace eval test_ns_1 {
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
         namespace export cmd1 cmd3
     }
+} -body {
     namespace eval test_ns_2 {
         namespace import -force ::test_ns_1::*
     }
     list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd3 hello]
-} [list [lsort {::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd3: hello}]
-test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} {
+} -result {{::test_ns_2::cmd1 ::test_ns_2::cmd3} {cmd3: hello}}
+test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
+        namespace export cmd1 cmd3
+    }
+} -body {
     namespace eval test_ns_1 {
         namespace export
     }
-} {cmd1 cmd3}
-test namespace-26.7 {NamespaceExportCmd, -clear resets export list} {
+} -result {cmd1 cmd3}
+test namespace-26.7 {NamespaceExportCmd, -clear resets export list} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
+    }
+} -body {
+    namespace eval test_ns_1 {
+        namespace export cmd1 cmd3
+    }
+    namespace eval test_ns_2 {
+        namespace import ::test_ns_1::*
+    }
     namespace eval test_ns_1 {
         namespace export -clear cmd4
     }
@@ -1119,7 +1272,7 @@ test namespace-26.7 {NamespaceExportCmd, -clear resets export list} {
         namespace import ::test_ns_1::*
     }
     list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
-} [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
+} -result [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
 test namespace-26.8 {NamespaceExportCmd, -clear resets export list} {
     catch {namespace delete foo}
     namespace eval foo {
@@ -1202,14 +1355,23 @@ test namespace-29.4 {NamespaceInscopeCmd, simple case} {
     }
     namespace inscope test_ns_1 cmd
 } {::test_ns_1::cmd: v=747, args=}
-test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} {
+test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} -setup {
+    namespace eval test_ns_1 {
+        variable v 747
+        proc cmd {args} {
+            variable v
+            return "[namespace current]::cmd: v=$v, args=$args"
+        }
+    }
+} -body {
     list [namespace inscope test_ns_1 cmd x y z] \
          [namespace eval test_ns_1 [concat cmd [list x y z]]]
-} {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
-test namespace-29.6 {NamespaceInscopeCmd, 1400572} {
+} -result {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
+test namespace-29.6 {NamespaceInscopeCmd, 1400572} -setup {
+    namespace eval test_ns_1 {}
+} -body {
     namespace inscope test_ns_1 {info level 0}
-} {namespace inscope test_ns_1 {info level 0}}
-
+} -result {namespace inscope test_ns_1 {info level 0}}
 
 test namespace-30.1 {NamespaceOriginCmd, bad args} {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
@@ -1330,7 +1492,8 @@ test namespace-34.3 {NamespaceWhichCmd, single arg is always command name} {
 test namespace-34.4 {NamespaceWhichCmd, bad args} {
     list [catch {namespace which a b} msg] $msg
 } {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
-test namespace-34.5 {NamespaceWhichCmd, command lookup} {
+test namespace-34.5 {NamespaceWhichCmd, command lookup} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
     namespace eval test_ns_1 {
         namespace export cmd*
         variable v1 111
@@ -1343,6 +1506,7 @@ test namespace-34.5 {NamespaceWhichCmd, command lookup} {
         variable v2 222
         proc p {} {}
     }
+} -body {
     namespace eval test_ns_3 {
         namespace import ::test_ns_2::*
         variable v3 333
@@ -1352,26 +1516,59 @@ test namespace-34.5 {NamespaceWhichCmd, command lookup} {
              [namespace which -command ::test_ns_2::cmd2] \
              [catch {namespace which -command ::test_ns_2::noSuchCmd} msg] $msg
     }
-} {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
-test namespace-34.6 {NamespaceWhichCmd, -command is default} {
+} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
+test namespace-34.6 {NamespaceWhichCmd, -command is default} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        namespace export cmd*
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace export *
+        namespace import ::test_ns_1::*
+        proc p {} {}
+    }
+    namespace eval test_ns_3 {
+        namespace import ::test_ns_2::*
+    }
+} -body {
     namespace eval test_ns_3 {
         list [namespace which foreach] \
              [namespace which p] \
              [namespace which cmd1] \
              [namespace which ::test_ns_2::cmd2]
     }
-} {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}
-test namespace-34.7 {NamespaceWhichCmd, variable lookup} {
+} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}
+test namespace-34.7 {NamespaceWhichCmd, variable lookup} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        namespace export cmd*
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace export *
+        namespace import ::test_ns_1::*
+        variable v2 222
+        proc p {} {}
+    }
+    namespace eval test_ns_3 {
+        variable v3 333
+        namespace import ::test_ns_2::*
+    }
+} -body {
     namespace eval test_ns_3 {
         list [namespace which -variable env] \
              [namespace which -variable v3] \
              [namespace which -variable ::test_ns_2::v2] \
              [catch {namespace which -variable ::test_ns_2::noSuchVar} msg] $msg
     }
-} {::env ::test_ns_3::v3 ::test_ns_2::v2 0 {}}
+} -result {::env ::test_ns_3::v3 ::test_ns_2::v2 0 {}}
 
-test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} {
+test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} -setup {
     catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
     namespace eval test_ns_1 {
         proc p {} {
             namespace delete [namespace current]
@@ -1379,7 +1576,7 @@ test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} {
         }
     }
     test_ns_1::p
-} {::test_ns_1}
+} -result {::test_ns_1}
 test namespace-35.2 {FreeNsNameInternalRep, resulting ref count == 0} {
     namespace eval test_ns_1 {
         proc q {} {
@@ -2107,6 +2304,68 @@ test namespace-50.4 {chained ensembles affect error messages} -body {
     rename a {}
     rename c {}
 }
+test namespace-50.5 {[4402cfa58c]} -setup {
+    proc bar {ev} {}
+    proc bingo {xx} {}
+    namespace ensemble create -command launch -map {foo bar event bingo}
+    set result {}
+} -body {
+    catch {launch foo} m; lappend result $m
+    catch {launch ev} m; lappend result $m
+    catch {launch foo} m; lappend result $m
+} -cleanup {
+    rename launch {}
+    rename bingo {}
+    rename bar {}
+} -result {{wrong # args: should be "launch foo ev"} {wrong # args: should be "launch event xx"} {wrong # args: should be "launch foo ev"}}
+test namespace-50.6 {[4402cfa58c]} -setup {
+    proc target {x y} {}
+    namespace ensemble create -command e2 -map {s2 target}
+    namespace ensemble create -command e1 -map {s1 e2}
+    set result {}
+} -body {
+    set s s
+    catch {e1 s1 s2 a} m; lappend result $m
+    catch {e1 $s s2 a} m; lappend result $m
+    catch {e1 s1 $s a} m; lappend result $m
+    catch {e1 $s $s a} m; lappend result $m
+} -cleanup {
+    rename e1 {}
+    rename e2 {}
+    rename target {}
+} -result {{wrong # args: should be "e1 s1 s2 x y"} {wrong # args: should be "e1 s1 s2 x y"} {wrong # args: should be "e1 s1 s2 x y"} {wrong # args: should be "e1 s1 s2 x y"}}
+test namespace-50.7 {[4402cfa58c]} -setup {
+    proc target {x y} {}
+    namespace ensemble create -command e2 -map {s2 target}
+    namespace ensemble create -command e1 -map {s1 e2} -parameters foo
+    set result {}
+} -body {
+    set s s
+    catch {e1 s2 s1 a} m; lappend result $m
+    catch {e1 $s s1 a} m; lappend result $m
+    catch {e1 s2 $s a} m; lappend result $m
+    catch {e1 $s $s a} m; lappend result $m
+} -cleanup {
+    rename e1 {}
+    rename e2 {}
+    rename target {}
+} -result {{wrong # args: should be "e1 s2 s1 x y"} {wrong # args: should be "e1 s2 s1 x y"} {wrong # args: should be "e1 s2 s1 x y"} {wrong # args: should be "e1 s2 s1 x y"}}
+test namespace-50.8 {[f961d7d1dd]} -setup {
+    proc target {} {}
+    namespace ensemble create -command e -map {s target} -parameters {{a b}}
+} -body {
+    e
+} -returnCodes error -result {wrong # args: should be "e {a b} subcommand ?arg ...?"} -cleanup {
+    rename e {}
+    rename target {}
+}
+test namespace-50.9 {[cea0344a51]} -body {
+    namespace eval foo {
+       namespace eval bar {
+           namespace delete foo
+       }
+    }
+} -returnCodes error -result {unknown namespace "foo" in namespace delete command}
 
 test namespace-51.1 {name resolution path control} -body {
     namespace eval ::test_ns_1 {
@@ -2928,6 +3187,22 @@ test namespace-53.10 {ensembles: nested rewrite} -setup {
     0 {1 v}\
     1 {wrong # args: should be "ns v x z2 a2"}\
     0 {2 v v2}}
+test namespace-53.11 {ensembles: nested rewrite} -setup {
+    namespace eval ns {
+       namespace export x
+       namespace eval x {
+           proc z2 {a1 a2} {list 2 $a1 $a2}
+           namespace export z*
+           namespace ensemble create -parameter p
+       }
+       namespace ensemble create
+    }
+} -body {
+    list [catch {ns x 1 z2} msg] $msg
+} -cleanup {
+    namespace delete ns
+    unset -nocomplain msg
+} -result {1 {wrong # args: should be "ns x 1 z2 a2"}}
 
 test namespace-54.1 {leak on namespace deletion} -constraints {memory} \
 -setup {
@@ -2953,6 +3228,45 @@ test namespace-54.1 {leak on namespace deletion} -constraints {memory} \
 test namespace-55.1 {compiled ensembles inside compiled ensembles: Bug 6d2f249a01} {
     info class [format %s constructor] oo::object
 } ""
+
+test namespace-56.1 {bug f97d4ee020: mutually-entangled deletion} {
+    namespace eval ::testing {
+       proc abc {} {}
+       proc def {} {}
+       trace add command abc delete "rename ::testing::def {}; #"
+       trace add command def delete "rename ::testing::abc {}; #"
+    }
+    namespace delete ::testing
+} {}
+test namespace-56.2 {bug f97d4ee020: mutually-entangled deletion} {
+    namespace eval ::testing {
+       namespace eval abc {proc xyz {} {}}
+       namespace eval def {proc xyz {} {}}
+       trace add command abc::xyz delete "namespace delete ::testing::def {}; #"
+       trace add command def::xyz delete "namespace delete ::testing::abc {}; #"
+    }
+    namespace delete ::testing
+} {}
+test namespace-56.3 {bug f97d4ee020: mutually-entangled deletion} {
+    namespace eval ::testing {
+       variable gone {}
+       oo::class create CB {
+           variable cmd
+           constructor other {set cmd $other}
+           destructor {rename $cmd {}; lappend ::testing::gone $cmd}
+       }
+       namespace eval abc {
+           ::testing::CB create def ::testing::abc::ghi
+           ::testing::CB create ghi ::testing::abc::def
+       }
+       namespace delete abc
+       try {
+           return [lsort $gone]
+       } finally {
+           namespace delete ::testing
+       }
+    }
+} {::testing::abc::def ::testing::abc::ghi}
 \f
 # cleanup
 catch {rename cmd1 {}}
index 895f7ed..2601c37 100644 (file)
@@ -2017,6 +2017,12 @@ test oo-15.10 {variable binding must not bleed through oo::copy} -setup {
 test oo-16.1 {OO: object introspection} -body {
     info object
 } -returnCodes 1 -result "wrong \# args: should be \"info object subcommand ?arg ...?\""
+test oo-16.1.1 {OO: object introspection} -body {
+    catch {info object} m o
+    dict get $o -errorinfo
+} -result "wrong \# args: should be \"info object subcommand ?arg ...?\"
+    while executing
+\"info object\""
 test oo-16.2 {OO: object introspection} -body {
     info object class NOTANOBJECT
 } -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
@@ -2156,6 +2162,12 @@ test oo-16.14 {OO: object introspection: TIP #436} -setup {
 test oo-17.1 {OO: class introspection} -body {
     info class
 } -returnCodes 1 -result "wrong \# args: should be \"info class subcommand ?arg ...?\""
+test oo-17.1.1 {OO: class introspection} -body {
+    catch {info class} m o
+    dict get $o -errorinfo
+} -result "wrong \# args: should be \"info class subcommand ?arg ...?\"
+    while executing
+\"info class\""
 test oo-17.2 {OO: class introspection} -body {
     info class superclass NOTANOBJECT
 } -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
@@ -3412,6 +3424,38 @@ test oo-27.22 {variables declaration uniqueifies: Bug 3396896} -setup {
 } -cleanup {
     foo destroy
 } -result {v t}
+test oo-27.23 {variable resolver leakage: Bug 1493a43044} -setup {
+    oo::class create Super
+    oo::class create Master {
+       superclass Super
+       variable member1 member2
+       constructor {} {
+           set member1 master1
+           set member2 master2
+       }
+       method getChild {} {
+           Child new [self]
+       }
+    }
+    oo::class create Child {
+       superclass Super
+       variable member1 result
+       constructor {m} {
+           set [namespace current]::member1 child1
+           set ns [info object namespace $m]
+           namespace upvar $ns member1 l1 member2 l2
+           upvar 1 member1 l3 member2 l4
+           [format namespace] upvar $ns member1 l5 member2 l6
+           [format upvar] 1 member1 l7 member2 l8
+           set result [list $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8]
+       }
+       method result {} {return $result}
+    }
+} -body {
+    [[Master new] getChild] result
+} -cleanup {
+    Super destroy
+} -result {master1 master2 master1 master2 master1 master2 master1 master2}
 
 # A feature that's not supported because the mechanism may change without
 # warning, but is supposed to work...
index a6e07a2..504d063 100644 (file)
@@ -13,7 +13,7 @@
 # See the file "license.terms" for information on usage and redistribution
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
-package require tcltest
+package require tcltest 2
 namespace import ::tcltest::*
 
 ::tcltest::loadTestedCommands
@@ -37,7 +37,7 @@ proc getArgs args {
     global argv
     set argv $args
 }
-
+\f
 # Basic argument parsing.
 
 test parseOld-1.1 {basic argument parsing} {
@@ -296,6 +296,7 @@ test parseOld-8.4 {semi-colons} {
 # The following checks are to ensure that the interpreter's result
 # gets re-initialized by Tcl_Eval in all the right places.
 
+set a 22
 test parseOld-9.1 {result initialization} {concat abc} abc
 test parseOld-9.2 {result initialization} {concat abc; proc foo {} {}} {}
 test parseOld-9.3 {result initialization} {concat abc; proc foo {} $a} {}
@@ -408,6 +409,8 @@ test parseOld-11.7 {long values} {
     set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
     llength $b
 } 43
+# Duplicate action of previous test
+llength [set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]]
 test parseOld-11.8 {long values} {
     set b
 } $a
@@ -538,8 +541,12 @@ test parseOld-15.4 {TclScriptEnd procedure} {
 test parseOld-15.5 {TclScriptEnd procedure} {
     info complete "xyz \[abc"
 } {0}
-
+\f
 # cleanup
 set argv $savedArgv
 ::tcltest::cleanupTests
 return
+
+# Local Variables:
+# mode: tcl
+# End:
index 0f78212..2072559 100644 (file)
@@ -19,7 +19,7 @@ testConstraint reg 0
 if {[testConstraint win]} {
     if {![catch {
            ::tcltest::loadTestedCommands
-           set ::regver [package require registry 1.3.1]
+           set ::regver [package require registry 1.3.2]
        }]} {
        testConstraint reg 1
     }
@@ -33,7 +33,7 @@ testConstraint english [expr {
 \f
 test registry-1.0 {check if we are testing the right dll} {win reg} {
     set ::regver
-} {1.3.1}
+} {1.3.2}
 test registry-1.1 {argument parsing for registry command} {win reg} {
     list [catch {registry} msg] $msg
 } {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
index e73ea50..f3d22e5 100644 (file)
@@ -135,6 +135,9 @@ test resolver-1.5 {cmdNameObj sharing vs. cmd resolver: other than global NS} -s
            z
        }
     }
+    namespace eval :: {
+       variable r2 ""
+    }
 } -constraints testinterpresolver -body {
     set r0 [namespace eval ::ns2 {x}]
     set r1 [namespace eval ::ns2 {z}]
index 94c1755..6c9c6c9 100644 (file)
@@ -211,8 +211,8 @@ test safe-7.3 {check that safe subinterpreters work} {
 } {ok {} 0}
 
 # test source control on file name
+set i "a"
 test safe-8.1 {safe source control on file} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
 } -body {
     safe::interpCreate $i
@@ -221,7 +221,6 @@ test safe-8.1 {safe source control on file} -setup {
     safe::interpDelete $i
 } -result {wrong # args: should be "source ?-encoding E? fileName"}
 test safe-8.2 {safe source control on file} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
 } -body {
     safe::interpCreate $i
@@ -230,7 +229,6 @@ test safe-8.2 {safe source control on file} -setup {
     safe::interpDelete $i
 } -result {wrong # args: should be "source ?-encoding E? fileName"}
 test safe-8.3 {safe source control on file} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     set log {}
     proc safe-test-log {str} {lappend ::log $str}
@@ -245,7 +243,6 @@ test safe-8.3 {safe source control on file} -setup {
     safe::interpDelete $i
 } -result {1 {permission denied} {{ERROR for slave a : ".": is a directory}}}
 test safe-8.4 {safe source control on file} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     set log {}
     proc safe-test-log {str} {global log; lappend log $str}
@@ -260,7 +257,6 @@ test safe-8.4 {safe source control on file} -setup {
     safe::interpDelete $i
 } -result {1 {permission denied} {{ERROR for slave a : "/abc/def": not in access_path}}}
 test safe-8.5 {safe source control on file} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     set log {}
     proc safe-test-log {str} {global log; lappend log $str}
@@ -279,7 +275,6 @@ test safe-8.5 {safe source control on file} -setup {
     safe::interpDelete $i
 } -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah]:no such file or directory"]]
 test safe-8.6 {safe source control on file} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     set log {}
     proc safe-test-log {str} {global log; lappend log $str}
@@ -296,7 +291,6 @@ test safe-8.6 {safe source control on file} -setup {
     safe::interpDelete $i
 } -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah.tcl]:no such file or directory"]]
 test safe-8.7 {safe source control on file} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     set log {}
     proc safe-test-log {str} {global log; lappend log $str}
@@ -315,7 +309,6 @@ test safe-8.7 {safe source control on file} -setup {
     safe::interpDelete $i
 } -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] xxxxxxxxxxx.tcl]:no such file or directory"]]
 test safe-8.8 {safe source forbids -rsrc} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     safe::interpCreate $i
 } -body {
@@ -349,8 +342,8 @@ test safe-8.10 {safe source and return} -setup {
     removeFile $returnScript
 } -result ok
 
+set i "a"
 test safe-9.1 {safe interps' deleteHook} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     set res {}
 } -body {
@@ -365,7 +358,6 @@ test safe-9.1 {safe interps' deleteHook} -setup {
     list [interp eval $i exit] $res
 } -result {{} {arg1 arg2 a}}
 test safe-9.2 {safe interps' error in deleteHook} -setup {
-    set i "a"
     catch {safe::interpDelete $i}
     set res {}
     set log {}
@@ -531,14 +523,14 @@ test safe-11.7.1 {testing safe encoding} -setup {
 } -body {
     catch {interp eval $i encoding convertfrom} m o
     dict get $o -errorinfo
-} -returnCodes ok -cleanup {
+} -returnCodes ok -match glob -cleanup {
     unset -nocomplain m o
     safe::interpDelete $i
 } -result {wrong # args: should be "encoding convertfrom ?encoding? data"
     while executing
 "encoding convertfrom"
     invoked from within
-"::interp invokehidden interp1 encoding convertfrom"
+"::interp invokehidden interp* encoding convertfrom"
     invoked from within
 "encoding convertfrom"
     invoked from within
@@ -555,14 +547,14 @@ test safe-11.8.1 {testing safe encoding} -setup {
 } -body {
     catch {interp eval $i encoding convertto} m o
     dict get $o -errorinfo
-} -returnCodes ok -cleanup {
+} -returnCodes ok -match glob -cleanup {
     unset -nocomplain m o
     safe::interpDelete $i
 } -result {wrong # args: should be "encoding convertto ?encoding? data"
     while executing
 "encoding convertto"
     invoked from within
-"::interp invokehidden interp1 encoding convertto"
+"::interp invokehidden interp* encoding convertto"
     invoked from within
 "encoding convertto"
     invoked from within
index 94b6901..1c68f91 100644 (file)
@@ -14,7 +14,7 @@
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
 if {[lsearch [namespace children] ::tcltest] == -1} {
-    package require tcltest
+    package require tcltest 2
     namespace import -force ::tcltest::*
 }
 
@@ -865,6 +865,8 @@ test set-old-10.13 {array enumeration errors} {
     list [catch {array done a b c} msg] $msg
 } {1 {wrong # args: should be "array donesearch arrayName searchId"}}
 test set-old-10.14 {array enumeration errors} {
+    catch {unset a}
+    set a(a) a
     list [catch {array done a b} msg] $msg
 } {1 {illegal search identifier "b"}}
 test set-old-10.15 {array enumeration errors} {
index 18119f5..374ff7a 100644 (file)
@@ -22,7 +22,7 @@ testConstraint testset2 [llength [info commands testset2]]
 
 catch {unset x}
 catch {unset i}
-
+\f
 test set-1.1 {TclCompileSetCmd: missing variable name} {
     list [catch {set} msg] $msg
 } {1 {wrong # args: should be "set varName ?newValue?"}}
@@ -39,16 +39,18 @@ test set-1.4 {TclCompileSetCmd: simple variable name in quotes} {
     set i 17
     list [set "i"] $i
 } {17 17}
-test set-1.5 {TclCompileSetCmd: simple variable name in braces} {
+test set-1.5 {TclCompileSetCmd: simple variable name in braces} -setup {
     catch {unset {a simple var}}
+} -body {
     set {a simple var} 27
     list [set {a simple var}] ${a simple var}
-} {27 27}
-test set-1.6 {TclCompileSetCmd: simple array variable name} {
+} -result {27 27}
+test set-1.6 {TclCompileSetCmd: simple array variable name} -setup {
     catch {unset a}
+} -body {
     set a(foo) 37
     list [set a(foo)] $a(foo)
-} {37 37}
+} -result {37 37}
 test set-1.7 {TclCompileSetCmd: non-simple (computed) variable name} {
     set x "i"
     set i 77
@@ -149,22 +151,24 @@ test set-1.14 {TclCompileSetCmd: simple local name, >255 locals} {
     }
     260locals
 } {1234}
-test set-1.15 {TclCompileSetCmd: variable is array} {
+test set-1.15 {TclCompileSetCmd: variable is array} -setup {
     catch {unset a}
+} -body {
     set x 27
     set x [set a(foo) 11]
     catch {unset a}
     set x
-} 11
-test set-1.16 {TclCompileSetCmd: variable is array, elem substitutions} {
+} -result 11
+test set-1.16 {TclCompileSetCmd: variable is array, elem substitutions} -setup {
     catch {unset a}
+} -body {
     set i 5
     set x 789
     set a(foo5) 27
     set x [set a(foo$i)]
     catch {unset a}
     set x
-} 27
+} -result 27
 
 test set-1.17 {TclCompileSetCmd: doing assignment, simple int} {
     set i 5
@@ -211,7 +215,7 @@ test set-1.25 {TclCompileSetCmd: var is array, braced (no subs)} {
 test set-1.26 {TclCompileSetCmd: various array constructs} {
     # Test all kinds of array constructs that TclCompileSetCmd
     # may feel inclined to tamper with.
-    proc p {} {
+    apply {{} {
        set a x
        set be(hej) 1                                   ; # hej
        set be($a) 1                                    ; # x
@@ -230,28 +234,33 @@ test set-1.26 {TclCompileSetCmd: various array constructs} {
        set [string range bet 0 1](foo) 1               ; # foo
        set be([set be(a:$a)][set b\e($a)]) 1           ; # 51
        return [lsort [array names be]]
-    }
-    p
+    }}
 } [lsort {hej x $a x,hej x,x c(x ww a:x hej,1,hej hug {a a} {x ,ugg,hej} x,h"ej
 {b c} foo 51}]; # " just a matching end quote
 
-test set-2.1 {set command: runtime error, bad variable name} {
+test set-2.1 {set command: runtime error, bad variable name} -setup {
     unset -nocomplain {"foo}
+} -body {
     list [catch {set {"foo}} msg] $msg $::errorInfo
-} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+} -result {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
     while executing
 "set {"foo}"}}
-test set-2.2 {set command: runtime error, not array variable} {
-    catch {unset b}
+# Stop my editor highlighter " from being confused
+test set-2.2 {set command: runtime error, not array variable} -setup {
+    unset -nocomplain b
+} -body {
     set b 44
     list [catch {set b(123)} msg] $msg
-} {1 {can't read "b(123)": variable isn't array}}
-test set-2.3 {set command: runtime error, errors in reading variables} {
-    catch {unset a}
+} -result {1 {can't read "b(123)": variable isn't array}}
+test set-2.3 {set command: runtime error, errors in reading variables} -setup {
+    unset -nocomplain a
+} -body {
     set a(6) 44
     list [catch {set a(18)} msg] $msg
-} {1 {can't read "a(18)": no such element in array}}
-test set-2.4 {set command: runtime error, readonly variable} -body {
+} -result {1 {can't read "a(18)": no such element in array}}
+test set-2.4 {set command: runtime error, readonly variable} -setup {
+    unset -nocomplain x
+} -body {
     proc readonly args {error "variable is read-only"}
     set x 123
     trace var x w readonly
@@ -260,12 +269,18 @@ test set-2.4 {set command: runtime error, readonly variable} -body {
     while executing
 *
 "set x 1"}}
-test set-2.5 {set command: runtime error, basic array operations} {
+test set-2.5 {set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+} -body {
+    array set a {}
     list [catch {set a(other)} msg] $msg
-} {1 {can't read "a(other)": no such element in array}}
-test set-2.6 {set command: runtime error, basic array operations} {
+} -result {1 {can't read "a(other)": no such element in array}}
+test set-2.6 {set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+} -body {
+    array set a {}
     list [catch {set a} msg] $msg
-} {1 {can't read "a": variable is array}}
+} -result {1 {can't read "a": variable is array}}
 
 # Test the uncompiled version of set
 
@@ -479,25 +494,29 @@ test set-3.24 {uncompiled set command: too many arguments} {
     $z msg
 } {wrong # args: should be "set varName ?newValue?"}
 
-test set-4.1 {uncompiled set command: runtime error, bad variable name} {
+test set-4.1 {uncompiled set command: runtime error, bad variable name} -setup {
     unset -nocomplain {"foo}
+} -body {
     set z set
     list [catch {$z {"foo}} msg] $msg $::errorInfo
-} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+} -result {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
     while executing
 "$z {"foo}"}}
-test set-4.2 {uncompiled set command: runtime error, not array variable} {
-    set z set
+# Stop my editor highlighter " from being confused
+test set-4.2 {uncompiled set command: runtime error, not array variable} -setup {
     catch {unset b}
+} -body {
+    set z set
     $z b 44
     list [catch {$z b(123)} msg] $msg
-} {1 {can't read "b(123)": variable isn't array}}
-test set-4.3 {uncompiled set command: runtime error, errors in reading variables} {
-     set z set
-   catch {unset a}
+} -result {1 {can't read "b(123)": variable isn't array}}
+test set-4.3 {uncompiled set command: runtime error, errors in reading variables} -setup {
+    catch {unset a}
+} -body {
+    set z set
     $z a(6) 44
     list [catch {$z a(18)} msg] $msg
-} {1 {can't read "a(18)": no such element in array}}
+} -result {1 {can't read "a(18)": no such element in array}}
 test set-4.4 {uncompiled set command: runtime error, readonly variable} -body {
     set z set
     proc readonly args {error "variable is read-only"}
@@ -508,27 +527,33 @@ test set-4.4 {uncompiled set command: runtime error, readonly variable} -body {
     while executing
 *
 "$z x 1"}}
-test set-4.5 {uncompiled set command: runtime error, basic array operations} {
+test set-4.5 {uncompiled set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+    array set a {}
+} -body {
     set z set
     list [catch {$z a(other)} msg] $msg
-} {1 {can't read "a(other)": no such element in array}}
-test set-4.6 {set command: runtime error, basic array operations} {
+} -result {1 {can't read "a(other)": no such element in array}}
+test set-4.6 {set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+    array set a {}
+} -body {
     set z set
     list [catch {$z a} msg] $msg
-} {1 {can't read "a": variable is array}}
+} -result {1 {can't read "a": variable is array}}
 
-test set-5.1 {error on malformed array name} testset2 {
+test set-5.1 {error on malformed array name} -constraints testset2 -setup {
     unset -nocomplain z
+} -body {
     catch {testset2 z(a) b} msg
     catch {testset2 z(b) a} msg1
     list $msg $msg1
-} {{can't read "z(a)(b)": variable isn't array} {can't read "z(b)(a)": variable isn't array}}
-
+} -result {{can't read "z(a)(b)": variable isn't array} {can't read "z(b)(a)": variable isn't array}}
 # In a mem-debug build, this test will crash unless Bug 3602706 is fixed.
 test set-5.2 {Bug 3602706} -body {
     testset2 ::tcl_platform not-in-there
 } -returnCodes error -result * -match glob
-
+\f
 # cleanup
 catch {unset a}
 catch {unset b}
@@ -537,3 +562,7 @@ catch {unset x}
 catch {unset z}
 ::tcltest::cleanupTests
 return 
+
+# Local Variables:
+# mode: tcl
+# End:
index 8473602..d43c41c 100644 (file)
@@ -1782,7 +1782,6 @@ test socket_$af-13.1 {Testing use of shared socket between two threads} -body {
         set i 0
         vwait x
         close $f
-       thread::wait
     }]]
     set port [thread::send $serverthread {set listen}]
     set s [socket $localhost $port]
index a66525e..140a270 100644 (file)
@@ -728,6 +728,16 @@ test stringComp-14.3 {Bug 0dca3bfa8f} {
        expr {$arg ne $argCopy}
     }} abcde
 } 1
+test stringComp-14.4 {Bug 1af8de570511} {
+    apply {{x y} {
+       # Generate an unshared string value
+       set val ""
+       for { set i 0 } { $i < $x } { incr i } {
+           set val [format "0%s" $val]
+       }
+       string replace $val[unset val] 1 1 $y
+    }} 4 x
+} 0x00
 
 ## string tolower
 ## not yet bc
index e66678b..728a018 100644 (file)
@@ -46,6 +46,7 @@ makeFile {
 
 cd [temporaryDirectory]
 testConstraint exec [llength [info commands exec]]
+\f
 # test -help
 # Child processes because -help [exit]s.
 test tcltest-1.1 {tcltest -help} {exec} {
@@ -1824,9 +1825,13 @@ test tcltest-26.2 {Bug/RFE 1017151} -setup {
 ---- errorInfo: body error
 *
 ---- errorInfo(cleanup): cleanup error*}
-
+\f
 cleanupTests
 }
 
 namespace delete ::tcltest::test
 return
+
+# Local Variables:
+# mode: tcl
+# End:
index 5a374c4..73f1091 100644 (file)
@@ -45,6 +45,14 @@ testConstraint teststaticpkg [llength [info commands teststaticpkg]]
 testConstraint testsimplefilesystem \
        [llength [info commands testsimplefilesystem]]
 
+proc loadIfNotPresent {pkg args} {
+    global testDir ext
+    set loaded [lmap x [info loaded {*}$args] {lindex $x 1}]
+    if {[string totitle $pkg] ni $loaded} {
+       load [file join $testDir $pkg$ext]
+    }
+}
+\f
 # Basic tests: parameter testing...
 test unload-1.1 {basic errors} -returnCodes error -body {
     unload
@@ -73,7 +81,7 @@ set pkgua_detached {}
 set pkgua_unloaded {}
 # Tests for loading/unloading in trusted (non-safe) interpreters...
 test unload-2.1 {basic loading of non-unloadable package, with guess for package name} [list $dll $loaded] {
-    load [file join $testDir pkga$ext]
+    loadIfNotPresent pkga
     list [pkga_eq abc def] [lsort [info commands pkga_*]]
 } {0 {pkga_eq pkga_quote}}
 test unload-2.2 {basic loading of unloadable package, with guess for package name} [list $dll $loaded] {
@@ -82,28 +90,43 @@ test unload-2.2 {basic loading of unloadable package, with guess for package nam
            [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
            $pkgua_loaded $pkgua_detached $pkgua_unloaded
 } {{} {} {} {} 0 {pkgua_eq pkgua_quote} . {} {}}
-test unload-2.3 {basic unloading of non-unloadable package, with guess for package name} [list $dll $loaded] {
-    list [catch {unload [file join $testDir pkga$ext]} msg] \
-           [string map [list [file join $testDir pkga$ext] file] $msg]
-} {1 {file "file" cannot be unloaded under a trusted interpreter}}
-test unload-2.4 {basic unloading of unloadable package, with guess for package name} [list $dll $loaded] {
+test unload-2.3 {basic unloading of non-unloadable package, with guess for package name} -setup {
+    loadIfNotPresent pkga
+} -constraints [list $dll $loaded] -returnCodes error -match glob -body {
+    unload [file join $testDir pkga$ext]
+} -result {file "*" cannot be unloaded under a trusted interpreter}
+test unload-2.4 {basic unloading of unloadable package, with guess for package name} -setup {
+    loadIfNotPresent pkgua
+} -constraints [list $dll $loaded] -body {
     list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
            [unload [file join $testDir pkgua$ext]] \
            [info commands pkgua_*] \
            $pkgua_loaded $pkgua_detached $pkgua_unloaded
-} {. {} {} {} {} . . .}
-test unload-2.5 {reloading of unloaded package, with guess for package name} [list $dll $loaded] {
+} -result {. {} {} {} {} . . .}
+test unload-2.5 {reloading of unloaded package, with guess for package name} -setup {
+    if {$pkgua_loaded eq ""} {
+       loadIfNotPresent pkgua
+       unload [file join $testDir pkgua$ext]
+    }
+} -constraints [list $dll $loaded] -body {
     list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
            [load [file join $testDir pkgua$ext]] \
            [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
            $pkgua_loaded $pkgua_detached $pkgua_unloaded
-} {. . . {} 0 {pkgua_eq pkgua_quote} .. . .}
-test unload-2.6 {basic unloading of re-loaded package, with guess for package name} [list $dll $loaded] {
+} -result {. . . {} 0 {pkgua_eq pkgua_quote} .. . .}
+test unload-2.6 {basic unloading of re-loaded package, with guess for package name} -setup {
+    # Establish expected state
+    if {$pkgua_loaded eq ""} {
+       loadIfNotPresent pkgua
+       unload [file join $testDir pkgua$ext]
+       load [file join $testDir pkgua$ext]
+    }
+} -constraints [list $dll $loaded] -body {
     list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
            [unload [file join $testDir pkgua$ext]] \
            [info commands pkgua_*] \
            $pkgua_loaded $pkgua_detached $pkgua_unloaded
-} {.. . . {} {} .. .. ..}
+} -result {.. . . {} {} .. .. ..}
 
 # Tests for loading/unloading in safe interpreters...
 interp create -safe child
@@ -127,38 +150,52 @@ test unload-3.2 {basic loading of unloadable package in a safe interpreter, with
            [lsort [child eval info commands pkgua_*]] \
            [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
 } {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
-test unload-3.3 {unloading of a package that has never been loaded from a safe interpreter} \
-       [list $dll $loaded] {
-    list [catch {unload [file join $testDir pkga$ext] {} child} msg] \
-         [string map [list [file join $testDir pkga$ext] file] $msg]
-} {1 {file "file" has never been loaded in this interpreter}}
-test unload-3.4 {basic unloading of a non-unloadable package from a safe interpreter, with guess for package name} \
-       [list $dll $loaded] {
-    list [catch {unload [file join $testDir pkgb$ext] {} child} msg] \
-         [string map [list [file join $testDir pkgb$ext] file] $msg]
-} {1 {file "file" cannot be unloaded under a safe interpreter}}
-test unload-3.5 {basic unloading of an unloadable package from a safe interpreter, with guess for package name} \
-       [list $dll $loaded] {
+test unload-3.3 {unloading of a package that has never been loaded from a safe interpreter} -setup {
+    loadIfNotPresent pkga
+} -constraints [list $dll $loaded] -returnCodes error -match glob -body {
+    unload [file join $testDir pkga$ext] {} child
+} -result {file "*" has never been loaded in this interpreter}
+test unload-3.4 {basic unloading of a non-unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {[lsearch -index 1 [info loaded child] Pkgb] == -1} {
+       load [file join $testDir pkgb$ext] pKgB child
+    }
+} -constraints [list $dll $loaded] -returnCodes error -match glob -body {
+    unload [file join $testDir pkgb$ext] {} child
+} -result {file "*" cannot be unloaded under a safe interpreter}
+test unload-3.5 {basic unloading of an unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {[lsearch -index 1 [info loaded child] Pkgua] == -1} {
+       load [file join $testDir pkgua$ext] pkgua child
+    }
+} -constraints [list $dll $loaded] -body {
     list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
            [unload [file join $testDir pkgua$ext] {} child] \
            [child eval info commands pkgua_*] \
            [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
-} {{. {} {}} {} {} {. . .}}
-test unload-3.6 {reloading of unloaded package in a safe interpreter, with guess for package name} \
-       [list $dll $loaded] {
+} -result {{. {} {}} {} {} {. . .}}
+test unload-3.6 {reloading of unloaded package in a safe interpreter, with guess for package name} -setup {
+    if {[child eval set pkgua_loaded] eq ""} {
+       load [file join $testDir pkgua$ext] {} child
+       unload [file join $testDir pkgua$ext] {} child
+    }
+} -constraints [list $dll $loaded] -body {
     list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
            [load [file join $testDir pkgua$ext] {} child] \
            [child eval pkgua_eq abc def] \
            [lsort [child eval info commands pkgua_*]] \
            [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
-} {{. . .} {} 0 {pkgua_eq pkgua_quote} {.. . .}}
-test unload-3.7 {basic unloading of re-loaded package from a safe interpreter, with package name conversion} \
-       [list $dll $loaded] {
+} -result {{. . .} {} 0 {pkgua_eq pkgua_quote} {.. . .}}
+test unload-3.7 {basic unloading of re-loaded package from a safe interpreter, with package name conversion} -setup {
+    if {[child eval set pkgua_loaded] eq ""} {
+       load [file join $testDir pkgua$ext] {} child
+       unload [file join $testDir pkgua$ext] {} child
+       load [file join $testDir pkgua$ext] {} child
+    }
+} -constraints [list $dll $loaded] -body {
     list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
            [unload [file join $testDir pkgua$ext] pKgUa child] \
            [child eval info commands pkgua_*] \
            [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
-} {{.. . .} {} {} {.. .. ..}}
+} -result {{.. . .} {} {} {.. .. ..}}
 
 # Tests for loading/unloading of a package among multiple interpreters...
 interp create child-trusted
@@ -167,56 +204,89 @@ child-trusted eval {
     set pkgua_detached {}
     set pkgua_unloaded {}
 }
+array set load {M 0 C 0 T 0}
 ## Load package in main trusted interpreter...
-test unload-4.1 {loading of unloadable package in trusted interpreter, with guess for package name} \
-       [list $dll $loaded] {
+test unload-4.1 {loading of unloadable package in trusted interpreter, with guess for package name} -setup {
+    set pkgua_loaded ""
+    set pkgua_detached ""
+    set pkgua_unloaded ""
+    incr load(M)
+} -constraints [list $dll $loaded] -body {
     list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
            [load [file join $testDir pkgua$ext]] \
            [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
            [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
-} {{.. .. ..} {} 0 {pkgua_eq pkgua_quote} {... .. ..}}
+} -result {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
 ## Load package in child-safe interpreter...
-test unload-4.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} \
-       [list $dll $loaded] {
+test unload-4.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} -setup {
+    child eval {
+       set pkgua_loaded ""
+       set pkgua_detached ""
+       set pkgua_unloaded ""
+    }
+    incr load(C)
+} -constraints [list $dll $loaded] -body {
     list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
            [load [file join $testDir pkgua$ext] pKgUA child] \
            [child eval pkgua_eq abc def] \
            [lsort [child eval info commands pkgua_*]] \
            [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
-} {{.. .. ..} {} 0 {pkgua_eq pkgua_quote} {... .. ..}}
+} -result {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
 ## Load package in child-trusted interpreter...
-test unload-4.3 {basic loading of unloadable package in a second trusted interpreter, with package name conversion} \
-       [list $dll $loaded] {
+test unload-4.3 {basic loading of unloadable package in a second trusted interpreter, with package name conversion} -setup {
+    incr load(T)
+} -constraints [list $dll $loaded] -body {
     list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
            [load [file join $testDir pkgua$ext] pkguA child-trusted] \
            [child-trusted eval pkgua_eq abc def] \
            [lsort [child-trusted eval info commands pkgua_*]] \
            [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
-} {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+} -result {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
 ## Unload the package from the main trusted interpreter...
-test unload-4.4 {basic unloading of unloadable package from trusted interpreter, with guess for package name} \
-       [list $dll $loaded] {
+test unload-4.4 {basic unloading of unloadable package from trusted interpreter, with guess for package name} -setup {
+    if {!$load(M)} {
+       load [file join $testDir pkgua$ext]
+    }
+    if {!$load(C)} {
+       load [file join $testDir pkgua$ext] {} child
+       incr load(C)
+    }
+    if {!$load(T)} {
+       load [file join $testDir pkgua$ext] {} child-trusted
+       incr load(T)
+    }
+} -constraints [list $dll $loaded] -body {
     list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
            [unload [file join $testDir pkgua$ext]] \
            [info commands pkgua_*] \
            [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
-} {{... .. ..} {} {} {... ... ..}}
+} -result {{. {} {}} {} {} {. . {}}}
 ## Unload the package from the child safe interpreter...
-test unload-4.5 {basic unloading of unloadable package from a safe interpreter, with guess for package name} \
-       [list $dll $loaded] {
+test unload-4.5 {basic unloading of unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {!$load(C)} {
+       load [file join $testDir pkgua$ext] {} child
+    }
+    if {!$load(T)} {
+       load [file join $testDir pkgua$ext] {} child-trusted
+       incr load(T)
+    }
+} -constraints [list $dll $loaded] -body {
     list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
            [unload [file join $testDir pkgua$ext] {} child] \
            [child eval info commands pkgua_*] \
            [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
-} {{... .. ..} {} {} {... ... ..}}
+} -result {{. {} {}} {} {} {. . {}}}
 ## Unload the package from the child trusted interpreter...
-test unload-4.6 {basic unloading of unloadable package from a safe interpreter, with guess for package name} \
-       [list $dll $loaded] {
+test unload-4.6 {basic unloading of unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {!$load(T)} {
+       load [file join $testDir pkgua$ext] {} child-trusted
+    }
+} -constraints [list $dll $loaded] -body {
     list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
            [unload [file join $testDir pkgua$ext] {} child-trusted] \
            [child-trusted eval info commands pkgua_*] \
            [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
-} {{. {} {}} {} {} {. . .}}
+} -result {{. {} {}} {} {} {. . .}}
 
 test unload-5.1 {unload a module loaded from vfs} \
      -constraints [list $dll $loaded testsimplefilesystem] \
@@ -230,9 +300,7 @@ test unload-5.1 {unload a module loaded from vfs} \
        list [catch {unload simplefs:/pkgua$ext} msg] $msg
     } \
     -result {0 {}}
-
-
-
+\f
 # cleanup
 interp delete child
 interp delete child-trusted
index 0410469..9ecc0d5 100644 (file)
@@ -101,6 +101,105 @@ test uplevel-4.4 {error: not enough args} -returnCodes error -body {
        uplevel 1
     }}
 } -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
+test uplevel-4.5 {level parsing} {
+    apply {{} {uplevel 0 {}}}
+} {}
+test uplevel-4.6 {level parsing} {
+    apply {{} {uplevel #0 {}}}
+} {}
+test uplevel-4.7 {level parsing} {
+    apply {{} {uplevel [expr 0] {}}}
+} {}
+test uplevel-4.8 {level parsing} {
+    apply {{} {uplevel #[expr 0] {}}}
+} {}
+test uplevel-4.9 {level parsing} {
+    apply {{} {uplevel -0 {}}}
+} {}
+test uplevel-4.10 {level parsing} {
+    apply {{} {uplevel #-0 {}}}
+} {}
+test uplevel-4.11 {level parsing} {
+    apply {{} {uplevel [expr -0] {}}}
+} {}
+test uplevel-4.12 {level parsing} {
+    apply {{} {uplevel #[expr -0] {}}}
+} {}
+test uplevel-4.13 {level parsing} {
+    apply {{} {uplevel 1 {}}}
+} {}
+test uplevel-4.14 {level parsing} {
+    apply {{} {uplevel #1 {}}}
+} {}
+test uplevel-4.15 {level parsing} {
+    apply {{} {uplevel [expr 1] {}}}
+} {}
+test uplevel-4.16 {level parsing} {
+    apply {{} {uplevel #[expr 1] {}}}
+} {}
+test uplevel-4.17 {level parsing} {
+    apply {{} {uplevel -0xffffffff {}}}
+} {}
+test uplevel-4.18 {level parsing} {
+    apply {{} {uplevel #-0xffffffff {}}}
+} {}
+test uplevel-4.19 {level parsing} {
+    apply {{} {uplevel [expr -0xffffffff] {}}}
+} {}
+test uplevel-4.20 {level parsing} {
+    apply {{} {uplevel #[expr -0xffffffff] {}}}
+} {}
+test uplevel-4.21 {level parsing} -body {
+    apply {{} {uplevel -1 {}}}
+} -returnCodes error -result {invalid command name "-1"}
+test uplevel-4.22 {level parsing} -body {
+    apply {{} {uplevel #-1 {}}}
+} -returnCodes error -result {bad level "#-1"}
+test uplevel-4.23 {level parsing} -body {
+    apply {{} {uplevel [expr -1] {}}}
+} -returnCodes error -result {invalid command name "-1"}
+test uplevel-4.24 {level parsing} -body {
+    apply {{} {uplevel #[expr -1] {}}}
+} -returnCodes error -result {bad level "#-1"}
+test uplevel-4.25 {level parsing} -body {
+    apply {{} {uplevel 0xffffffff {}}}
+} -returnCodes error -result {bad level "0xffffffff"}
+test uplevel-4.26 {level parsing} -body {
+    apply {{} {uplevel #0xffffffff {}}}
+} -returnCodes error -result {bad level "#0xffffffff"}
+test uplevel-4.27 {level parsing} -body {
+    apply {{} {uplevel [expr 0xffffffff] {}}}
+} -returnCodes error -result {bad level "4294967295"}
+test uplevel-4.28 {level parsing} -body {
+    apply {{} {uplevel #[expr 0xffffffff] {}}}
+} -returnCodes error -result {bad level "#4294967295"}
+test uplevel-4.29 {level parsing} -body {
+    apply {{} {uplevel 0.2 {}}}
+} -returnCodes error -result {bad level "0.2"}
+test uplevel-4.30 {level parsing} -body {
+    apply {{} {uplevel #0.2 {}}}
+} -returnCodes error -result {bad level "#0.2"}
+test uplevel-4.31 {level parsing} -body {
+    apply {{} {uplevel [expr 0.2] {}}}
+} -returnCodes error -result {bad level "0.2"}
+test uplevel-4.32 {level parsing} -body {
+    apply {{} {uplevel #[expr 0.2] {}}}
+} -returnCodes error -result {bad level "#0.2"}
+test uplevel-4.33 {level parsing} -body {
+    apply {{} {uplevel .2 {}}}
+} -returnCodes error -result {invalid command name ".2"}
+test uplevel-4.34 {level parsing} -body {
+    apply {{} {uplevel #.2 {}}}
+} -returnCodes error -result {bad level "#.2"}
+test uplevel-4.35 {level parsing} -body {
+    apply {{} {uplevel [expr .2] {}}}
+} -returnCodes error -result {bad level "0.2"}
+test uplevel-4.36 {level parsing} -body {
+    apply {{} {uplevel #[expr .2] {}}}
+} -returnCodes error -result {bad level "#0.2"}
+
+
+
 
 proc a2 {} {
     uplevel a3
index ceb1af7..a03dd6c 100644 (file)
@@ -302,7 +302,7 @@ test utf-21.1 {TclUniCharIsAlnum} {
 } {1}
 test utf-21.2 {unicode alnum char in regc_locale.c} {
     # this returns 1 with Unicode 7 compliance
-    list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220]
+    list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220_\u203f\u2040\u2054\ufe33\ufe34\ufe4d\ufe4e\ufe4f\uff3f]
 } {1 1}
 test utf-21.3 {unicode print char in regc_locale.c} {
     # this returns 1 with Unicode 7 compliance
index 0531746..297034a 100644 (file)
@@ -44,10 +44,12 @@ test var-1.1 {TclLookupVar, Array handling} -setup {
     set arr(foo) 37
     list [$x i] $i [$x arr(foo)] $arr(foo)
 } -result {11 11 38 38}
+set ::x "global value"
+namespace eval test_ns_var {
+    variable x "namespace value"
+}
 test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {
-    set x "global value"
     namespace eval test_ns_var {
-        variable x "namespace value"
         proc p {} {
             global x  ;# specifies TCL_GLOBAL_ONLY to get global x
             return $x
@@ -167,7 +169,9 @@ test var-1.17 {TclLookupVar, resurrect array element via upvar to deleted array:
        set result
     }
 } {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
-test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} {
+test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} -setup {
+    unset -nocomplain test_ns_var::x
+} -body {
     namespace eval test_ns_var {
        variable result {}
        variable x
@@ -179,7 +183,7 @@ test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array:
         namespace delete [namespace current]
        set result
     }
-} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
+} -result {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
 test var-1.19 {TclLookupVar, right error message when parsing variable name} -body {
     [format set] thisvar(doesntexist)
 } -returnCodes error -result {can't read "thisvar(doesntexist)": no such variable}
@@ -261,6 +265,7 @@ test var-3.7 {MakeUpvar, my var has ::s} -setup {
     }
 } -result {789789}
 test var-3.8 {MakeUpvar, my var already exists in global ns} -setup {
+    upvar #0 aaaaa xxxxx
     catch {unset aaaaa}
     catch {unset xxxxx}
 } -body {
@@ -274,6 +279,8 @@ test var-3.9 {MakeUpvar, my var has invalid ns name} -setup {
 } -returnCodes error -body {
     set aaaaa 789789
     upvar #0 aaaaa test_ns_fred::lnk
+} -cleanup {
+    unset ::aaaaa
 } -result {can't create "test_ns_fred::lnk": parent namespace doesn't exist}
 test var-3.10 {MakeUpvar, between namespaces} -body {
     namespace eval {} {
@@ -282,8 +289,6 @@ test var-3.10 {MakeUpvar, between namespaces} -body {
        set foo::bar 1
        list $bar $foo::bar
     }
-} -cleanup {
-    unset ::aaaaa
 } -result {1 1}
 test var-3.11 {MakeUpvar, my var looks like array elem} -setup {
     catch {unset aaaaa}
@@ -322,9 +327,11 @@ test var-5.2 {Tcl_GetVariableFullName, namespace variable} {
         namespace which -variable martha
     }
 } {::test_ns_var::martha}
-test var-5.3 {Tcl_GetVariableFullName, namespace variable} {
+test var-5.3 {Tcl_GetVariableFullName, namespace variable} -setup {
+    namespace eval test_ns_var {variable martha}
+} -body {
     namespace which -variable test_ns_var::martha
-} {::test_ns_var::martha}
+} -result {::test_ns_var::martha}
 
 test var-6.1 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
     namespace eval test_ns_var {
@@ -348,6 +355,7 @@ test var-6.2 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
     test_ns_var::p
 } {java}
 test var-6.3 {Tcl_GlobalObjCmd, variable named {} qualified by a namespace name} {
+    namespace eval ::test_ns_var::test_ns_nested {}
     set ::test_ns_var::test_ns_nested:: 24
     apply {{} {
         global ::test_ns_var::test_ns_nested::
@@ -389,20 +397,26 @@ test var-7.2 {Tcl_VariableObjCmd, if new and no value, leave undefined} {
     }
     list [info exists test_ns_var::two] [catch {set test_ns_var::two} msg] $msg
 } {0 1 {can't read "test_ns_var::two": no such variable}}
-test var-7.3 {Tcl_VariableObjCmd, "define" var already created above} {
+test var-7.3 {Tcl_VariableObjCmd, "define" var already created above} -setup {
+    catch {namespace delete test_ns_var}
+    namespace eval test_ns_var {variable one 1}
+} -body {
     namespace eval test_ns_var {
         variable two 2
     }
     list [lsort [info vars test_ns_var::*]] \
          [namespace eval test_ns_var {set two}]
-} [list [lsort {::test_ns_var::two ::test_ns_var::one}] 2]
-test var-7.4 {Tcl_VariableObjCmd, list of vars} {
+} -result [list [lsort {::test_ns_var::two ::test_ns_var::one}] 2]
+test var-7.4 {Tcl_VariableObjCmd, list of vars} -setup {
+    catch {namespace delete test_ns_var}
+    namespace eval test_ns_var {variable one 1; variable two 2}
+} -body {
     namespace eval test_ns_var {
         variable three 3 four 4
     }
     list [lsort [info vars test_ns_var::*]] \
          [namespace eval test_ns_var {expr $three+$four}]
-} [list [lsort {::test_ns_var::four ::test_ns_var::three ::test_ns_var::two ::test_ns_var::one}] 7]
+} -result [list [lsort {::test_ns_var::four ::test_ns_var::three ::test_ns_var::two ::test_ns_var::one}] 7]
 test var-7.5 {Tcl_VariableObjCmd, value for last var is optional} -setup {
     catch {unset a}
     catch {unset five}
@@ -476,7 +490,9 @@ test var-7.9 {Tcl_VariableObjCmd, mark as namespace var so var persists until na
        [lsort {::test_ns_var2::x ::test_ns_var2::z}] 0 0\
        {1 {can't unset "test_ns_var2::z": no such variable}}\
        {}]
-test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
+    namespace eval test_ns_var { variable eight 8 }
+} -body {
     namespace eval test_ns_var {
         proc p {} {
             variable eight
@@ -484,14 +500,16 @@ test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link v
         }
         p
     }
-} {8 eight}
-test var-7.11 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+} -result {8 eight}
+test var-7.11 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
+    namespace eval test_ns_var { variable eight 8 }
+} -body {
     proc p {} {   ;# note this proc is at global :: scope
         variable test_ns_var::eight
         list [set eight] [info vars]
     }
     p
-} {8 eight}
+} -result {8 eight}
 test var-7.12 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
     namespace eval test_ns_var {
         variable {} {My name is empty}
@@ -774,7 +792,7 @@ test var-17.1 {TclArraySet [Bug 1669489]} -setup {
 
 test var-18.1 {array unset and unset traces: Bug 2939073} -setup {
     set already 0
-    unset x
+    unset -nocomplain x
 } -body {
     array set x {e 1 i 1}
     trace add variable x unset {apply {args {
@@ -921,6 +939,34 @@ test var-22.0 {leak in array element unset: Bug a3309d01db} -setup {
     rename getbytes {}
     rename doit {}
 } -result 0
+test var-22.1 {leak in localVarName intrep: Bug 80304238ac} -setup {
+    proc getbytes {} {
+       lindex [split [memory info] \n] 3 3
+    }
+    proc doit {} {
+       interp create slave
+       slave eval {
+           proc doit script {
+               eval $script
+               set foo bar
+           }
+           doit {foreach foo baz {}}
+       }
+       interp delete slave
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+       doit
+        set tmp $end
+        set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    array unset A
+    rename getbytes {}
+    rename doit {}
+} -result 0
 
 \f
 catch {namespace delete ns}
index 7a486ba..8a040d8 100644 (file)
@@ -251,9 +251,10 @@ test zlib-8.8 {transformation and fconfigure} -setup {
 } -constraints zlib -body {
     zlib push compress $outSide -dictionary $spdyDict
     fconfigure $outSide -blocking 0 -translation binary -buffering none
-    fconfigure $inSide -blocking 0 -translation binary
+    fconfigure $inSide -blocking 1 -translation binary
     puts -nonewline $outSide $spdyHeaders
     chan pop $outSide
+    chan close $outSide
     set compressed [read $inSide]
     catch {zlib decompress $compressed} err opt
     list [string length [zlib compress $spdyHeaders]] \
@@ -269,10 +270,11 @@ test zlib-8.9 {transformation and fconfigure} -setup {
 } -constraints zlib -body {
     zlib push compress $outSide -dictionary $spdyDict
     fconfigure $outSide -blocking 0 -translation binary -buffering none
-    fconfigure $inSide -blocking 0 -translation binary
+    fconfigure $inSide -blocking 1 -translation binary
     puts -nonewline $outSide $spdyHeaders
     set result [fconfigure $outSide -checksum]
     chan pop $outSide
+    chan close $outSide
     $strm put -dictionary $spdyDict [read $inSide]
     lappend result [string length $spdyHeaders] [string length [$strm get]]
 } -cleanup {
@@ -285,9 +287,10 @@ test zlib-8.10 {transformation and fconfigure} -setup {
 } -constraints {zlib recentZlib} -body {
     zlib push deflate $outSide -dictionary $spdyDict
     fconfigure $outSide -blocking 0 -translation binary -buffering none
-    fconfigure $inSide -blocking 0 -translation binary
+    fconfigure $inSide -blocking 1 -translation binary
     puts -nonewline $outSide $spdyHeaders
     chan pop $outSide
+    chan close $outSide
     set compressed [read $inSide]
     catch {
        zlib inflate $compressed
@@ -306,9 +309,10 @@ test zlib-8.11 {transformation and fconfigure} -setup {
 } -constraints zlib -body {
     zlib push deflate $outSide -dictionary $spdyDict
     fconfigure $outSide -blocking 0 -translation binary -buffering none
-    fconfigure $inSide -blocking 0 -translation binary
+    fconfigure $inSide -blocking 1 -translation binary
     puts -nonewline $outSide $spdyHeaders
     chan pop $outSide
+    chan close $outSide
     $strm put -dictionary $spdyDict [read $inSide]
     list [string length $spdyHeaders] [string length [$strm get]]
 } -cleanup {
@@ -401,6 +405,26 @@ test zlib-8.16 {Bug 3603553: buffer transfer with large writes} -setup {
 } -cleanup {
     removeFile $file
 } -result 57647
+test zlib-8.17 {Bug dd260aaf: fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+} -constraints zlib -body {
+    zlib push inflate $inSide
+    zlib push deflate $outSide
+    list [chan configure $inSide -dictionary] [chan configure $outSide -dictionary]
+} -cleanup {
+    catch {close $inSide}
+    catch {close $outSide}
+} -result {{} {}}
+test zlib-8.18 {Bug dd260aaf: fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+} -constraints zlib -body {
+    zlib push inflate $inSide -dictionary "one two"
+    zlib push deflate $outSide -dictionary "one two"
+    list [chan configure $inSide -dictionary] [chan configure $outSide -dictionary]
+} -cleanup {
+    catch {close $inSide}
+    catch {close $outSide}
+} -result {{one two} {one two}}
 
 test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
     set sfile [makeFile {} testsrc.gz]
@@ -875,6 +899,24 @@ test zlib-11.3 {Bug 3595576 variant} -setup {
 } -cleanup {
     removeFile $file
 } -returnCodes error -result {can't set "noSuchNs::foo": parent namespace doesn't exist}
+
+test zlib-12.1 {Tk Bug 9eb55debc5} -constraints zlib -setup {
+    set stream [zlib stream compress]
+} -body {
+    for {set opts {};set y 0} {$y < 60} {incr y} {
+       for {set line {};set x 0} {$x < 100} {incr x} {
+           append line [binary format ccc $x $y 128]
+       }
+       if {$y == 59} {
+           set opts -finalize
+       }
+       $stream put {*}$opts $line
+    }
+    set data [$stream get]
+    list [string length $data] [string length [zlib decompress $data]]
+} -cleanup {
+    $stream close
+} -result {12026 18000}
 \f
 ::tcltest::cleanupTests
 return
index beede9e..9f2c6ca 100644 (file)
@@ -10,8 +10,6 @@
 # See the file "license.terms" for information on usage and redistribution
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
-package require Tcl 8.4
-
 namespace eval genStubs {
     # libraryName --
     #
index 6d4724f..2d03ab6 100644 (file)
@@ -2,8 +2,6 @@
 # \
 exec tclsh "$0" ${1+"$@"}
 
-package require Tcl 8.4
-
 # man2html.tcl --
 #
 # This file contains procedures that work in conjunction with the
index e8d29e8..64982ff 100644 (file)
@@ -5,8 +5,6 @@
 #
 # Copyright (c) 1996 by Sun Microsystems, Inc.
 
-package require Tcl 8.4
-
 # Global variables used by these scripts:
 #
 # state -      state variable that controls action of text proc.
index 163196e..e4ccedf 100644 (file)
@@ -6,8 +6,6 @@
 #
 # Copyright (c) 1996 by Sun Microsystems, Inc.
 
-package require Tcl 8.4
-
 # Global variables used by these scripts:
 #
 # NAME_file -  array indexed by NAME and containing file names used for
index 005919a..85c9ba9 100755 (executable)
@@ -30,8 +30,6 @@
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 #----------------------------------------------------------------------
 
-package require Tcl 8.5
-
 # Define the names of the Olson files that we need to load.
 # We avoid the solar time files and the leap seconds.
 
index 1ceceb9..d607905 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env tclsh
 
-if {[catch {package require Tcl 8.6} msg]} {
+if {[catch {package require Tcl 8.6-} msg]} {
     puts stderr "ERROR: $msg"
     puts stderr "If running this script from 'make html', set the\
        NATIVE_TCLSH environment\nvariable to point to an installed\
index bc73118..7b3d820 100644 (file)
@@ -657,7 +657,7 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in
 #      $(SHELL) config.status
 
 clean: clean-packages
-       rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \
+       rm -rf *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \
                errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@
        cd dltest ; $(MAKE) clean
 
@@ -849,8 +849,8 @@ install-libraries: libraries
            done;
        @echo "Installing package msgcat 1.6.0 as a Tcl Module";
        @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.0.tm;
-       @echo "Installing package tcltest 2.3.8 as a Tcl Module";
-       @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.8.tm;
+       @echo "Installing package tcltest 2.4.0 as a Tcl Module";
+       @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.0.tm;
 
        @echo "Installing package platform 1.0.14 as a Tcl Module";
        @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.14.tm;
@@ -1596,7 +1596,7 @@ tclWinError.o: $(TOP_DIR)/win/tclWinError.c
 
 # DTrace support
 
-$(TCL_OBJS) $(STUB_LIB_OBJS) $(TCLSH_OBJS) $(TCLTEST_OBJS) $(XTTEST_OBJS): @DTRACE_HDR@
+$(TCL_OBJS) $(STUB_LIB_OBJS) $(TCLSH_OBJS) $(TCLTEST_OBJS) $(XTTEST_OBJS) $(TOMMATH_OBJS): @DTRACE_HDR@
 
 $(DTRACE_HDR): $(DTRACE_SRC)
        $(DTRACE) -h $(DTRACE_SWITCHES) -o $@ -s $(DTRACE_SRC)
index 2e774f7..38c3f9a 100755 (executable)
@@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 TCL_VERSION=8.6
 TCL_MAJOR_VERSION=8
 TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".5"
+TCL_PATCH_LEVEL=".6"
 VERSION=${TCL_VERSION}
 
 EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
index 5d4cfbe..1d86213 100755 (executable)
@@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [
 TCL_VERSION=8.6
 TCL_MAJOR_VERSION=8
 TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".5"
+TCL_PATCH_LEVEL=".6"
 VERSION=${TCL_VERSION}
 
 EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
index 4d615bf..1f1cbde 100755 (executable)
@@ -106,7 +106,7 @@ for Target in $Names; do
        First=$Target
        sed -e "/man\.macros/r $SrcDir/man.macros" -e "/man\.macros/d" \
            $ManPage > $Dir/$First
-       chmod 444 $Dir/$First
+       chmod 644 $Dir/$First
        $Gzip $Dir/$First
     else
        ln $SymOrLoc$First$Gz $Dir/$Target$Gz
index 3044311..8bf77f3 100644 (file)
@@ -4,7 +4,7 @@
 
 Name:          tcl
 Summary:       Tcl scripting language development environment
-Version:       8.6.5
+Version:       8.6.6
 Release:       2
 License:       BSD
 Group:         Development/Languages
index 48ba0cc..1457890 100644 (file)
@@ -433,9 +433,11 @@ Tcl_FinalizeNotifier(
                            "unable to write q to triggerPipe");
                }
                close(triggerPipe);
+               pthread_mutex_lock(&notifierMutex);
                while(triggerPipe != -1) {
                    pthread_cond_wait(&notifierCV, &notifierMutex);
                }
+               pthread_mutex_unlock(&notifierMutex);
                if (notifierThreadRunning) {
                    int result = pthread_join((pthread_t) notifierThread, NULL);
 
index 2d27a41..28ffe0a 100644 (file)
@@ -660,8 +660,8 @@ install-libraries: libraries install-tzdata install-msgs
            done;
        @echo "Installing package msgcat 1.6.0 as a Tcl Module";
        @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.0.tm;
-       @echo "Installing package tcltest 2.3.8 as a Tcl Module";
-       @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.3.8.tm;
+       @echo "Installing package tcltest 2.4.0 as a Tcl Module";
+       @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.0.tm;
        @echo "Installing package platform 1.0.14 as a Tcl Module";
        @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.14.tm;
        @echo "Installing package platform::shell 1.1.4 as a Tcl Module";
@@ -713,14 +713,14 @@ test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE)
        ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \
        -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \
        package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
-       package ifneeded registry 1.3.1 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32)
+       package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32)
 
 # Useful target to launch a built tclsh with the proper path,...
 runtest: binaries $(TCLSH) $(TEST_DLL_FILE)
        @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
        ./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \
        package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
-       package ifneeded registry 1.3.1 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT)
+       package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT)
 
 # This target can be used to run tclsh from the build directory via
 # `make shell SCRIPT=foo.tcl`
index 0ebe18a..3314f26 100644 (file)
@@ -34,6 +34,7 @@ tclsdl                0x10B20000      0x00080000
 vqtcl          0x10C00000      0x00010000\r
 tdbc           0x10C40000      0x00010000\r
 thread         0x10C80000      0x00020000\r
+nsf            0x10ca0000      0x00080000\r
 ;\r
 ; insert new packages here\r
 ;\r
index 2336111..e8e4b87 100755 (executable)
@@ -1311,7 +1311,7 @@ SHELL=/bin/sh
 TCL_VERSION=8.6
 TCL_MAJOR_VERSION=8
 TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".5"
+TCL_PATCH_LEVEL=".6"
 VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
 
 TCL_DDE_VERSION=1.4
index a72b993..8bb9c48 100644 (file)
@@ -14,7 +14,7 @@ SHELL=/bin/sh
 TCL_VERSION=8.6
 TCL_MAJOR_VERSION=8
 TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".5"
+TCL_PATCH_LEVEL=".6"
 VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
 
 TCL_DDE_VERSION=1.4
index ecfcecf..eb9a594 100644 (file)
@@ -589,13 +589,13 @@ test-core: setup $(TCLTEST) dlls $(CAT32)
 !if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"\r
        $(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile <<\r
                package ifneeded dde 1.4.0 [list load "$(TCLDDELIB:\=/)" dde]\r
-               package ifneeded registry 1.3.1 [list load "$(TCLREGLIB:\=/)" registry]\r
+               package ifneeded registry 1.3.2 [list load "$(TCLREGLIB:\=/)" registry]\r
 <<\r
 !else\r
        @echo Please wait while the tests are collected...\r
        $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << > tests.log\r
                package ifneeded dde 1.4.0 "$(TCLDDELIB:\=/)" dde]\r
-               package ifneeded registry 1.3.1 "$(TCLREGLIB:\=/)" registry]\r
+               package ifneeded registry 1.3.2 "$(TCLREGLIB:\=/)" registry]\r
 <<\r
        type tests.log | more\r
 !endif\r
index 25c6ea4..4d7500b 100755 (executable)
@@ -16,8 +16,9 @@
 #include "tclFileSystem.h"
 #include <winioctl.h>
 #include <shlobj.h>
-#include <lm.h>                /* For TclpGetUserHome(). */
+#include <lm.h>                        /* For TclpGetUserHome(). */
 #include <userenv.h>           /* For TclpGetUserHome(). */
+#include <aclapi.h>             /* For GetNamedSecurityInfo */
 
 #ifdef _MSC_VER
 #   pragma comment(lib, "userenv.lib")
@@ -1769,7 +1770,7 @@ NativeAccess(
  * NativeIsExec --
  *
  *     Determines if a path is executable. On windows this is simply defined
- *     by whether the path ends in any of ".exe", ".com", or ".bat"
+ *     by whether the path ends in a standard executable extension.
  *
  * Results:
  *     1 = executable, 0 = not.
@@ -1793,6 +1794,7 @@ NativeIsExec(
 
     if ((_tcsicmp(path+len-3, TEXT("exe")) == 0)
            || (_tcsicmp(path+len-3, TEXT("com")) == 0)
+           || (_tcsicmp(path+len-3, TEXT("cmd")) == 0)
            || (_tcsicmp(path+len-3, TEXT("bat")) == 0)) {
        return 1;
     }
@@ -1951,6 +1953,7 @@ NativeStat(
     unsigned short mode;
     unsigned int inode = 0;
     HANDLE fileHandle;
+    DWORD fileType = FILE_TYPE_UNKNOWN;
 
     /*
      * If we can use 'createFile' on this, then we can use the resulting
@@ -1958,6 +1961,14 @@ NativeStat(
      * other attributes reading APIs. If not, then we try to fall back on the
      * 'getFileAttributesExProc', and if that isn't available, then on even
      * simpler routines.
+     *
+     * Special consideration must be given to Windows hardcoded names
+     * like CON, NULL, COM1, LPT1 etc. For these, we still need to
+     * do the CreateFile as some may not exist (e.g. there is no CON
+     * in wish by default). However the subsequent GetFileInformationByHandle
+     * will fail. We do a WinIsReserved to see if it is one of the special
+     * names, and if successful, mock up a BY_HANDLE_FILE_INFORMATION
+     * structure.
      */
 
     fileHandle = CreateFile(nativePath, GENERIC_READ,
@@ -1968,19 +1979,26 @@ NativeStat(
        BY_HANDLE_FILE_INFORMATION data;
 
        if (GetFileInformationByHandle(fileHandle,&data) != TRUE) {
-           CloseHandle(fileHandle);
-           Tcl_SetErrno(ENOENT);
-           return -1;
-       }
-       CloseHandle(fileHandle);
-
+            fileType = GetFileType(fileHandle);
+            CloseHandle(fileHandle);
+            if (fileType != FILE_TYPE_CHAR && fileType != FILE_TYPE_DISK) {
+                Tcl_SetErrno(ENOENT);
+                return -1;
+            }
+            /* Mock up the expected structure */
+            memset(&data, 0, sizeof(data));
+            statPtr->st_atime = 0;
+            statPtr->st_mtime = 0;
+            statPtr->st_ctime = 0;
+        } else {
+            CloseHandle(fileHandle);
+            statPtr->st_atime = ToCTime(data.ftLastAccessTime);
+            statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
+            statPtr->st_ctime = ToCTime(data.ftCreationTime);
+        }
        attr = data.dwFileAttributes;
-
        statPtr->st_size = ((Tcl_WideInt) data.nFileSizeLow) |
                (((Tcl_WideInt) data.nFileSizeHigh) << 32);
-       statPtr->st_atime = ToCTime(data.ftLastAccessTime);
-       statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
-       statPtr->st_ctime = ToCTime(data.ftCreationTime);
 
        /*
         * On Unix, for directories, nlink apparently depends on the number of
@@ -2036,6 +2054,13 @@ NativeStat(
 
     dev = NativeDev(nativePath);
     mode = NativeStatMode(attr, checkLinks, NativeIsExec(nativePath));
+    if (fileType == FILE_TYPE_CHAR) {
+        mode &= ~S_IFMT;
+        mode |= S_IFCHR;
+    } else if (fileType == FILE_TYPE_DISK) {
+        mode &= ~S_IFMT;
+        mode |= S_IFBLK;
+    }
 
     statPtr->st_dev    = (dev_t) dev;
     statPtr->st_ino    = inode;
@@ -3109,6 +3134,68 @@ TclpUtime(
 }
 \f
 /*
+ *---------------------------------------------------------------------------
+ *
+ * TclWinFileOwned --
+ *
+ *     Returns 1 if the specified file exists and is owned by the current
+ *      user and 0 otherwise. Like the Unix case, the check is made using
+ *      the real process SID, not the effective (impersonation) one.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclWinFileOwned(
+    Tcl_Obj *pathPtr)          /* File whose ownership is to be checked */
+{
+    const TCHAR *native;
+    PSID ownerSid = NULL;
+    PSECURITY_DESCRIPTOR secd = NULL;
+    HANDLE token;
+    LPBYTE buf = NULL;
+    DWORD bufsz;
+    int owned = 0;
+
+    native = Tcl_FSGetNativePath(pathPtr);
+
+    if (GetNamedSecurityInfo((LPTSTR) native, SE_FILE_OBJECT,
+                             OWNER_SECURITY_INFORMATION, &ownerSid,
+                             NULL, NULL, NULL, &secd) != ERROR_SUCCESS) {
+        /* Either not a file, or we do not have access to it in which
+           case we are in all likelihood not the owner */
+        return 0;
+    }
+        
+    /* 
+     * Getting the current process SID is a multi-step process.
+     * We make the assumption that if a call fails, this process is
+     * so underprivileged it could not possibly own anything. Normally
+     * a process can *always* look up its own token.
+     */
+    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
+        /* Find out how big the buffer needs to be */
+        bufsz = 0;
+        GetTokenInformation(token, TokenUser, NULL, 0, &bufsz);
+        if (bufsz) {
+            buf = ckalloc(bufsz);
+            if (GetTokenInformation(token, TokenUser, buf, bufsz, &bufsz)) {
+                owned = EqualSid(ownerSid, ((PTOKEN_USER) buf)->User.Sid);
+            }
+        }
+        CloseHandle(token);
+    }
+
+    /* Free allocations and be done */
+    if (secd)
+        LocalFree(secd);            /* Also frees ownerSid */
+    if (buf)
+        ckfree(buf);
+    
+    return (owned != 0);        /* Convert non-0 to 1 */
+}
+    
+/*
  * Local Variables:
  * mode: c
  * c-basic-offset: 4
index 9df424f..6b098f8 100644 (file)
@@ -72,6 +72,7 @@ MODULE_SCOPE int      TclWinSymLinkCopyDirectory(const TCHAR *LinkOriginal,
                            const TCHAR *LinkCopy);
 MODULE_SCOPE int       TclWinSymLinkDelete(const TCHAR *LinkOriginal,
                            int linkOnly);
+MODULE_SCOPE int        TclWinFileOwned(Tcl_Obj *);
 #if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
 MODULE_SCOPE void      TclWinFreeAllocCache(void);
 MODULE_SCOPE void      TclFreeAllocCache(void *);
index aff8836..382addd 100644 (file)
@@ -897,7 +897,7 @@ TclpGetPid(
  *
  *     The complete Windows search path is searched to find the specified
  *     executable. If an executable by the given name is not found,
- *     automatically tries appending ".com", ".exe", and ".bat" to the
+ *     automatically tries appending standard extensions to the
  *     executable name.
  *
  * Results:
@@ -1292,7 +1292,7 @@ ApplicationType(
     Tcl_DString nameBuf, ds;
     const TCHAR *nativeName;
     TCHAR nativeFullPath[MAX_PATH];
-    static const char extensions[][5] = {"", ".com", ".exe", ".bat"};
+    static const char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"};
 
     /*
      * Look for the program as an external program. First try the name as it
@@ -1337,7 +1337,8 @@ ApplicationType(
        Tcl_DStringFree(&ds);
 
        ext = strrchr(fullName, '.');
-       if ((ext != NULL) && (strcasecmp(ext, ".bat") == 0)) {
+       if ((ext != NULL) && 
+            (strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") == 0)) {
            applType = APPL_DOS;
            break;
        }
index ca6b2bf..b486466 100644 (file)
@@ -360,6 +360,20 @@ typedef DWORD_PTR * PDWORD_PTR;
 #   define S_IFLNK        0120000  /* Symbolic Link */
 #endif
 
+/* 
+ * Windows compilers do not define S_IFBLK. However, Tcl uses it in
+ * GetTypeFromMode to identify blockSpecial devices based on the
+ * value in the statsbuf st_mode field. We have no other way to pass this
+ * from NativeStat on Windows so are forced to define it here.
+ * The definition here is essentially what is seen on Linux and MingW.
+ * XXX - the root problem is Tcl using Unix definitions instead of
+ * abstracting the structure into a platform independent one. Sigh - perhaps
+ * Tcl 9
+ */
+#ifndef S_IFBLK
+#   define S_IFBLK (S_IFDIR | S_IFCHR)
+#endif
+
 #ifndef S_ISREG
 #   ifdef S_IFREG
 #       define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
index 56aa991..5f7fd31 100644 (file)
@@ -163,7 +163,7 @@ Registry_Init(
     cmd = Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd,
            interp, DeleteCmd);
     Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, cmd);
-    return Tcl_PkgProvide(interp, "registry", "1.3.1");
+    return Tcl_PkgProvide(interp, "registry", "1.3.2");
 }
 \f
 /*
@@ -803,17 +803,17 @@ GetValue(
         * we get bogus data.
         */
 
-       while ((p < end) && *((Tcl_UniChar *) p) != 0) {
-           Tcl_UniChar *up;
+       while ((p < end) && *((WCHAR *) p) != 0) {
+           WCHAR *wp;
 
            Tcl_WinTCharToUtf((TCHAR *) p, -1, &buf);
            Tcl_ListObjAppendElement(interp, resultPtr,
                    Tcl_NewStringObj(Tcl_DStringValue(&buf),
                            Tcl_DStringLength(&buf)));
-           up = (Tcl_UniChar *) p;
+           wp = (WCHAR *) p;
 
-           while (*up++ != 0) {/* empty body */}
-           p = (char *) up;
+           while (*wp++ != 0) {/* empty body */}
+           p = (char *) wp;
            Tcl_DStringFree(&buf);
        }
        Tcl_SetObjResult(interp, resultPtr);
@@ -1332,7 +1332,7 @@ SetValue(
        data = (char *) Tcl_WinUtfToTChar(data, length, &buf);
 
        /*
-        * Include the null in the length, padding if needed for Unicode.
+        * Include the null in the length, padding if needed for WCHAR.
         */
 
        Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf)+1);
@@ -1393,9 +1393,10 @@ BroadcastValue(
     DWORD_PTR sendResult;
     int timeout = 3000;
     size_t len;
-    int unilen;
     const char *str;
     Tcl_Obj *objPtr;
+    WCHAR *wstr;
+    Tcl_DString ds;
 
     if (objc == 3) {
        str = Tcl_GetString(objv[1]);
@@ -1408,9 +1409,11 @@ BroadcastValue(
        }
     }
 
-    str = (char*)Tcl_GetUnicodeFromObj(objv[0], &unilen);
-    if (unilen == 0) {
-       str = NULL;
+    str = Tcl_GetString(objv[0]);
+    len = objv[0]->length;
+    wstr = (WCHAR *) Tcl_WinUtfToTChar(str, len, &ds);
+    if (Tcl_DStringLength(&ds) == 0) {
+       wstr = NULL;
     }
 
     /*
@@ -1418,11 +1421,12 @@ BroadcastValue(
      */
 
     result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE,
-           (WPARAM) 0, (LPARAM) str, SMTO_ABORTIFHUNG, (UINT) timeout, &sendResult);
+           (WPARAM) 0, (LPARAM) wstr, SMTO_ABORTIFHUNG, (UINT) timeout, &sendResult);
+    Tcl_DStringFree(&ds);
 
     objPtr = Tcl_NewObj();
-    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewLongObj((long) result));
-    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewLongObj((long) sendResult));
+    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewWideIntObj((Tcl_WideInt) result));
+    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewWideIntObj((Tcl_WideInt) sendResult));
     Tcl_SetObjResult(interp, objPtr);
 
     return TCL_OK;
index a022ed5..da2e60a 100644 (file)
@@ -2061,7 +2061,6 @@ Tcl_OpenTcpServer(
     char channelName[SOCK_CHAN_LENGTH];
     u_long flag = 1;           /* Indicates nonblocking mode. */
     const char *errorMsg = NULL;
-    ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
 
     if (TclpHasSockets(interp) != TCL_OK) {
        return NULL;
@@ -2177,6 +2176,7 @@ error:
     }
 
     if (statePtr != NULL) {
+       ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
 
        statePtr->acceptProc = acceptProc;
        statePtr->acceptProcData = acceptProcData;
index 1c9d483..ca26f08 100644 (file)
@@ -168,7 +168,6 @@ TclWinThreadStart(
                                 * from TclpThreadCreate */
 {
     WinThread *winThreadPtr = (WinThread *) lpParameter;
-    unsigned int fpmask;
     LPTHREAD_START_ROUTINE lpOrigStartAddress;
     LPVOID lpOrigParameter;
 
@@ -176,13 +175,11 @@ TclWinThreadStart(
        return TCL_ERROR;
     }
 
-    fpmask = _MCW_EM | _MCW_RC | _MCW_PC;
-
-#if defined(_MSC_VER) && _MSC_VER >= 1200
-    fpmask |= _MCW_DN;
+    _controlfp(winThreadPtr->fpControl, _MCW_EM | _MCW_RC | 0x03000000 /* _MCW_DN */
+#if !defined(_WIN64)
+           | _MCW_PC
 #endif
-
-    _controlfp(winThreadPtr->fpControl, fpmask);
+    );
 
     lpOrigStartAddress = winThreadPtr->lpStartAddress;
     lpOrigParameter = winThreadPtr->lpParameter;